在实现数组之前执行的JavaScript Promise和Promise.all(数组)

时间:2016-04-14 07:24:13

标签: javascript promise

我学习JavaScript承诺,这是一件非常棒的事情。但是当我使用promise.all(arr).then时会有一些混淆。请参阅以下代码,

var arr = [];

for(var i=0; i<2; i++){
    arr.push((function(){
        new Promise(function(resolve, reject) {
            setTimeout(function() {
                console.log('resolved !');
                resolve();
            }, 3000);
        });
    })());
}

Promise.all(arr).then(function() {
    console.log("Done"); 
});

我期待的结果是

resolved!
resolved!
Done

但实际结果是

Done
resolved!
resolved!

所以,在数组完成之前执行的Promise.all(arr).then,所以它没有捕获它的元素。我该怎么做呢?上面的代码只是示例,也许我改变了结构,如下面的代码没有问题,但由于我的应用程序结构,我应该使用for looppush

// Below working well, but I want use above shape(minimize change) 

var p1 = new Promise(function(resolve, reject) {
    setTimeout(function() {
        console.log('resolved #1');
        resolve();
    }, 1000);
});

var p2 = new Promise(function(resolve, reject) {
    setTimeout(function() {
        console.log('resolved #2');
        resolve();
    }, 2000);
});

var arr = [p1, p2];


Promise.all(arr).then(function() {
    console.log("Done");
});

1 个答案:

答案 0 :(得分:3)

作为georg said,您只是没有将承诺放在arr中,因为您永远不会从new Promise所包含的匿名函数中返回任何内容。该功能也完全没必要,所以:

&#13;
&#13;
var arr = [];

for (var i = 0; i < 2; i++) {
  arr.push(new Promise(function(resolve, reject) {
    setTimeout(function() {
      log('resolved !');
      resolve();
    }, 500);
  }));
}

Promise.all(arr).then(function() {
  log("Done");
});

function log(msg) {
  var p = document.createElement('p');
  p.appendChild(document.createTextNode(msg));
  document.body.appendChild(p);
}
&#13;
&#13;
&#13;

如果该函数存在,那么您可以捕获当前值i,只需确保您返回承诺:

&#13;
&#13;
var arr = [];

for (var i = 0; i < 2; i++) {
  arr.push(function(index) {
    return new Promise(function(resolve, reject) {
      setTimeout(function() {
        log('resolved with ' + index + ' !');
        resolve(index);
      }, 500);
    });
  }(i));
}

Promise.all(arr).then(function() {
  log("Done");
});

function log(msg) {
  var p = document.createElement('p');
  p.appendChild(document.createTextNode(msg));
  document.body.appendChild(p);
}
&#13;
&#13;
&#13;