0

I'm learning promise about ecma6,I want to get the json data by promise.then(),but it doesn't work by the callback of resolve.I test in chrome under version 44. the result is enter image description here

    <button type="button" id="get">get</button>
    <script type="text/javascript">
        var ele = document.getElementById('get');
        ele.addEventListener('click', testPromise, false);
        var getData = function (url) {
            var promise1 = new Promise(function (resolve, reject) {
                var xhr = new XMLHttpRequest();
                xhr.open('GET', url);
                xhr.setRequestHeader('Accept', 'application/json');
                xhr.send();
                xhr.onreadystatechange = handler;
                xhr.responseType = 'json';
                function handler () {
                    console.log('status: ' + this.status);
                    if (this.status === 200) {
                        console.log(this.response);
                        resolve(this.response);
                    } else {
                        reject(new Error(this.statusText));
                    }
                }
            });
            return promise1;
        }

        function testPromise() {
            getData('http://1.frontendlife.sinaapp.com/test/promise.json').then(function (json) {
                console.log(json);
            }, function (error) {
                console.log(error);
            });
        }
    </script>
mumu
  • 57
  • 2
  • 3
  • 11
  • 1
    `resolve` is not being called because it is being rejected( Cross-Origin Request Blocked ), the promise works just fine. – mido Aug 13 '15 at 04:05
  • but it under the same origin,why? – mumu Aug 13 '15 at 04:12
  • for us, it is cross-origin... what status do you get? – mido Aug 13 '15 at 04:17
  • Id' suggest you do `xhr.send()` AFTER you set the other `xhr` properties. Not sure if that causes a problem, but it looks like it could cause a problem the way it is. – jfriend00 Aug 13 '15 at 04:25
  • @mido22 access http://1.frontendlife.sinaapp.com/test/testPromise.html – mumu Aug 13 '15 at 04:28
  • you are getting an error in `ele.attachEvent('onclick', testPromise);`, you have commented the line that works! – jperelli Aug 13 '15 at 04:31
  • @jperelli I know,I want to test in IE,the problem is not the event listener,you can try in chrome. – mumu Aug 13 '15 at 04:35
  • @jfriend00 I set the other xhr properties before xhr.send( ),but it doesn't work sadly. – mumu Aug 13 '15 at 04:36
  • @doudou - IE does not yet support `Promise` in any version yet (the new Edge browser in Windows 10 does support it). You would have to use a third party library like Bluebird or Q for promises in IE. FYI, your linked page seems to work fine for me in Chrome 44. – jfriend00 Aug 13 '15 at 04:45
  • @jfriend00 In chrome's console,what does the line 37 code output?null/Object?my result image is attached in my question,you can see it. – mumu Aug 13 '15 at 05:01
  • @doudou - I looked into that and offer a fix in my answer below. – jfriend00 Aug 13 '15 at 05:23
  • possible duplicate of [How do I promisify native XHR?](http://stackoverflow.com/q/30008114/1048572) – Bergi Aug 13 '15 at 06:23

1 Answers1

2

You have a logic error in you xhr handler. You cannot examine the result of your XHR call until readyState === 4. You have one version in your question and a slightly different version in your linked page, but both can resolve or reject before readyState === 4 which gives you incomplete results.

Change it to this:

   <button type="button" id="get">get</button>
    <script type="text/javascript">
        var ele = document.getElementById('get');
        ele.addEventListener('click', testPromise, false);
        var getData = function (url) {
            var promise1 = new Promise(function (resolve, reject) {
                var xhr = new XMLHttpRequest();
                xhr.open('GET', url);
                xhr.setRequestHeader('Accept', 'application/json');
                xhr.send();
                xhr.onreadystatechange = handler;
                xhr.responseType = 'json';
                function handler () {
                    if (this.readyState === 4) {
                        console.log('status: ' + this.status);
                        if (this.status === 200) {
                            console.log(this.response);
                            resolve(this.response);
                        } else {
                            reject(new Error(this.statusText));
                        }
                    }
                }
            });
            return promise1;
        }

        function testPromise() {
            getData('http://1.frontendlife.sinaapp.com/test/promise.json').then(function (json) {
                console.log(json);
            }, function (error) {
                console.log(error);
            });
        }
    </script>
jfriend00
  • 683,504
  • 96
  • 985
  • 979