然后Promise.all.then在单个诺言完成之前执行

时间:2018-09-27 17:25:10

标签: javascript

以下示例代码表示了我们正在尝试做的事情,并且对console.log内部的Promises.all.then()为何在单个承诺未完成之前就已经完成感到困惑。我认为map语句可能与此有关,但不确定。

我使用map的目的是收集所有成功或失败的信息,并在以后进行批量操作时通知用户。

var requests = []; var success=[]; var failures = [];

requests.push(new Promise((resolve, reject) => setTimeout(() => resolve("foo success"), 2000)));
requests.push(new Promise((resolve, reject) => setTimeout(() => reject("bar failure"), 1000)));
requests.push(new Promise((resolve, reject) => setTimeout(() => resolve("foo2 success"), 2000)));
requests.push(new Promise((resolve, reject) => setTimeout(() => reject("bar2 failure"), 1000)));

Promise.all(requests.map(p => {
    p.then(r => {
        console.log(r)
        success.push(r);
    });
    p.catch((e) => { console.log(e); failures.push(e); });
})).then(function () { console.log("ALL promises completed")})

我可以知道以上代码有什么问题吗?我没有按照预期执行承诺吗??

3 个答案:

答案 0 :(得分:3)

这是因为您的requests.map(...)回调没有返回任何东西,因此您正在将Promises映射到undefined值。因此,您正在通过undefined调用来等待Promise.all值的数组。更改为以下内容:

Promise.all(requests.map(p => {
    p.then(r => {
      console.log(r)
      console.log("POSTed a record successfuly");
      success.push(r);
    });
    p.catch((e) => { console.log(e); failures.push(e); });
    return p;
})).then(function () { console.log("POSTED ALL")})

更新

正如@JoeFrambach指出的那样,如果您希望Promise.all包含原始requests承诺的内容,则需要返回原始承诺。由于这很可能是您想要做的,所以我已经更新了答案。

答案 1 :(得分:1)

只需从地图回调函数返回promise

var requests = []; var success=[]; var failures = [];

requests.push(new Promise((resolve, reject) => setTimeout(() => resolve("foo success"), 2000)));
requests.push(new Promise((resolve, reject) => setTimeout(() => reject("bar failure"), 1000)));
requests.push(new Promise((resolve, reject) => setTimeout(() => resolve("foo2 success"), 2000)));
requests.push(new Promise((resolve, reject) => setTimeout(() => reject("bar2 failure"), 1000)));

Promise.all(requests.map(p => {
    p.then(r => {
        console.log(r)
        success.push(r);
    });
    p.catch((e) => { console.log(e); failures.push(e); });
    return p; // ADD THIS LINE
})).then(function () { console.log("ALL promises completed")})
   .catch(function() {console.log("FAILED PROMISE ALL")});

答案 2 :(得分:0)

您需要在.map函数中返回一个Promise。 在.map函数中,将最后一行作为返回p。

承诺所有人都应承诺。您正在从地图函数返回未定义的数组,因此它立即得到解决。