按顺序执行原生JavaScript Promise

8
我需要为数组中的每个项目调用一个promise来执行一些异步任务,但我希望这些任务按顺序执行。
Promise.all仅用于创建一个新的promise,以合并promise列表,但它不会按顺序调用它们。
如何在不使用第三方库(如Q、bluebird等)的情况下,使用标准的promise api实现这一点?

为什么Promise.all不能满足任务要求? - elclanrs
1
@tarini 请看一下这篇文章,特别是“高级错误#3:promises vs promise factories”部分。 - Bartosz Gościński
1个回答

21

您可以使用.then()将Promise链接在一起,回调函数返回另一个Promise。假设您有三个函数a、b和c都返回一个Promise。您可以像这样链式地执行它们(按顺序执行):

a().then(b).then(c).then(function(result) {
   // all are done here
});

如果您在处理一个数组并且有一个返回Promise的函数 myFunc ,您想要为数组中的每个项目调用该函数,您可以使用一种标准的设计模式,即使用.reduce()来逐个遍历数组中的每个项目:

var items = [...];

items.reduce(function(p, item) {
    return p.then(function() {
        return myFunc(item);
    });
}, Promise.resolve());

事实上,这只是像第一个示例中一样链接一堆.then()处理程序,但使用.reduce()的结构为您遍历数组。


从ES2017开始,您还可以使用async/await来串行处理这样的数组:

async function processArray(arr) {
    for (let item of arr) {
        let result = await somePromiseReturningFunc(item);
        // do something with result here before
        // going on to next array item
    }
    return someFinalResult;
}

processArray(someArray).then(result => {
    // done processing array here
}).catch(err => {
    // handle error here
});

1
添加了一个使用 .reduce() 遍历数组来顺序执行 Promise 的示例。 - jfriend00
添加了一个使用 async/await 串行处理数组的示例。 - jfriend00

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接