承诺没有按预期解决

时间:2016-06-01 07:22:53

标签: javascript ecmascript-6

我是诺言世界的新手所以请在以下场景中启发我:

    function promiseDemo(fetch1,fetch2){
        return Promise.all([fetch1,fetch2]).then(function(values){
        return values[0]+values[1];
        });
    }

   promiseDemo(ajax('sample1.html'),ajax('sample2.html')).then(function(sum){
    console.log(sum);
   },function(){
      console.log('Whoopsie!!!!!'); 
   });


 function ajax(file){
    var httpRequest=new XMLHttpRequest();
    httpRequest.open('GET',file,true);
    httpRequest.onreadystatechange=function(){
    if( httpRequest.readyState == 4){
        if(httpRequest.status == 200){
            console.log('success');
            console.log(httpRequest.responseText);
            return Promise.resolve(httpRequest.responseText);   
        }else{
        console.log('unexpected 400 error');
        return 0;
    }
  }
 }
 httpRequest.send();
 }

上面的代码从两个文件sample1和sample2中获取样本html,并且仅当两个文件都被检索时才将文本附加到dom。但是即使reponseText与预期一样,我也会将值[0]和值[1]视为未定义。是问题吗?欢迎任何建议,谢谢你!!!!

3 个答案:

答案 0 :(得分:3)

如果您在return函数内的任何位置使用httpRequest.onreadystatechange,则不会从ajax返回值,而是从onreadystatechange事件本身返回。

如果您需要使用Promise包装回调代码,则需要使用Promise constructor

 function ajax(file) {
     return new Promise((resolve, reject) => {
          var httpRequest = new XMLHttpRequest();
          httpRequest.open('GET', file, true);
          httpRequest.onreadystatechange = function() {
              if (httpRequest.readyState == 4) {
                  if (httpRequest.status == 200) {
                      console.log('success');
                      console.log(httpRequest.responseText);
                      resolve(httpRequest.responseText);
                  } else {
                      console.log('unexpected 400 error');
                      reject(0);
                  }
              }
          }
          httpRequest.send();
     });
 }

仅供参考,有一种名为fetch的新方法已经实现了您的目标。您可以将其用作:

promiseDemo(fetch('sample1.html'),fetch('sample2.html')).then(function(sum){
    console.log(sum);
   },function(){
      console.log('Whoopsie!!!!!'); 
   });

浏览器的填充功能可在GitHub上找到。

答案 1 :(得分:0)

我相信您的ajax函数不会返回承诺,因此promiseDemo没有得到任何承诺值来解决。尝试检查传递给promiseDemo函数的内容。

如果出现问题,您可以通过在ajax函数中创建一个新的承诺来立即修复它,并在http请求回调函数中解析。

答案 2 :(得分:0)

这里的问题是ajax函数返回undefined,而不是应由onreadystatuschange函数解析/拒绝的Promise。我认为这对你有用......

 function ajax(file){
    return new Promise(function (resolve, reject) {
        var httpRequest=new XMLHttpRequest();

        httpRequest.open('GET', file, true);

        httpRequest.onreadystatechange = function(){
            if(httpRequest.readyState == 4){
                if(httpRequest.status == 200){
                    console.log('success');
                    console.log(httpRequest.responseText);
                    resolve(httpRequest.responseText);   
                }
                else {
                    reject({status: httpRequest.status});
                    return 0;
                }
            }

        }

        httpRequest.send();
    }
}