如何按顺序运行一系列promises

时间:2017-02-23 23:35:27

标签: javascript arrays node.js asynchronous promise

我需要在一系列项目上运行一些承诺,但我不知道数组的长度。我如何按顺序运行这些承诺?这就是我异步执行的方式:

const arrayABC = [a, b, c.....x, y, z] // length unknown
const promises = arrayABC.map(function(item) {
   doSomething(item)
   }
return Promise.all(promises)

我需要承诺逐一贯穿它们。

3 个答案:

答案 0 :(得分:0)

如果您使用蓝鸟 - http://bluebirdjs.com/docs/api/promise.each.html,那么您可以使用.each()按顺序运行它们。从文档注释中获取的示例

const Promise = require('bluebird')

let queue = [];

queue.push(function() {
  return new Promise(function(resolve, reject) {
    // Some asynchronous task.
    console.log("Processing item 1...");
    setTimeout(resolve, 3000);
  });
});

queue.push(function() {
  return new Promise(function(resolve, reject) {
    // Some asynchronous task.
    console.log("Processing item 2...");
    setTimeout(resolve, 1000);
  });
});

Promise.each(queue, function(queue_item) {
  // *Now* we call the function. Since it returns a promise, the next iteration will not run until it resolves.
  return queue_item();
});

答案 1 :(得分:-1)

以下映射是异步顺序,而您的代码是异步 parallel



function sequentialAsyncMap(array, fn) {
    var p = Promise.resolve();
    return Promise.all(array.map(
        (item, index, collection) => p = p.then(
            () => fn(item, index, collection)
        )
    ));
}

function delay(timeout, value) {
    return new Promise(resolve => {
        setTimeout(() => resolve(value), timeout);
    });
}

sequentialAsyncMap([1, 2, 3], i => {
    console.log(i);
    return delay(500, 2*i);
}).then(result => {
    console.log(result);
});




答案 2 :(得分:-1)

如果您需要访问所有Promises结果(就像使用Promise.all一样) - 您可以执行以下操作:

Promise.series = (array, fn, thisArg) => {
    var p = Promise.resolve();
    return Promise.all(Array.from(array).map((...args) => 
        p = p
        .then(() => fn.apply(thisArg, args))
    ));
};

然后您的代码变为

const arrayABC = [a, b, c.....x, y, z] // length unknown
return Promise.series(promises, doSomething);

回调(在本例中为doSomething)将传递参数item, index, array,就像Array#mapArray#forEach

thisArg是可选的,就像您将其用于Array#mapArray#forEach等的方式一样

替代Promise.series

Promise.series = (array, fn, thisArg) => 
    Array.from(array).reduce((promise, ...args) => 
        promise
        .then(results => 
            fn.apply(thisArg, args)
            .then(result => results.concat(result))
        ), Promise.resolve([])
    );

同样的结果,但不需要Promise.all