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

Promise and Promise.all(array) executed before array fulfilled

本文关键字:数组 Promise 执行 实现 all      更新时间:2024-06-26

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!

上面的代码只是一个例子。我更改了如下结构,代码不再有问题,但由于我的应用程序结构,我应该使用for循环和push

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");
});

正如georg所说,您只是没有将promise放在arr中,因为您从未从围绕new Promise封装的匿名函数返回任何内容。这个功能也是完全没有必要的,所以:

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);
}

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

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);
}