Promise 和 Promise.all(array) 在数组完成之前执行

ton*_*on1 2 javascript function promise es6-promise

回调Promise.all(arr).then在数组完成之前执行,因此它不会捕获其元素。我怎样才能正确地做到这一点?

\n

\r\n
\r\n
var arr = [];\n\nfor (var i = 0; i < 2; i++) {\n  arr.push((function() {\n    new Promise(function(resolve, reject) {\n      setTimeout(function() {\n        console.log("Resolved!");\n        resolve();\n      }, 3000);\n    });\n  })());\n}\n\nPromise.all(arr).then(function() {\n  console.log("Done");\n});
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

我的预期结果是:

\n
Resolved!\nResolved!\nDone\n
Run Code Online (Sandbox Code Playgroud)\n

但真实的结果是:

\n
Done\nResolved!\nResolved!\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

\r\n
\r\n
var p1 = new Promise(function(resolve, reject) {\n  setTimeout(function() {\n    console.log("Resolved #1");\n    resolve();\n  }, 1000);\n});\nvar p2 = new Promise(function(resolve, reject) {\n  setTimeout(function() {\n    console.log("Resolved #2");\n    resolve();\n  }, 2000);\n});\nvar arr = [p1, p2];\n\nPromise.all(arr).then(function() {\n  console.log("Done");\n});
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

T.J*_*der 5

正如georg 所说,您只是没有将承诺放入其中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);
}
Run Code Online (Sandbox Code Playgroud)

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

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);
}
Run Code Online (Sandbox Code Playgroud)