如何在拒绝中打破Bluebird promise.app()?

时间:2015-08-21 17:08:04

标签: javascript promise bluebird

我正在编写一个MongoDB索引器,并使用Bluebird作为我的承诺,当我想提交索引数组时,它可以正常工作。

我的问题是,如果其中一个promise被拒绝(即第一个),其余的索引仍会被调用。我想停止执行失败后的任何事情。

var arr = [{col1: 1}, {col2: 1}];

return bluebird.all(arr.map(function (index) {
    // This returns a promise
    return indexingFunction(index);
}));

2 个答案:

答案 0 :(得分:1)

您可以使用.each()

return bluebird.each(arr, function(item) {
  return indexingFunction(item);
});

答案 1 :(得分:0)

首先,您必须决定是否并行或按顺序运行所有异步操作。如果您并行启动所有操作,则所有请求都会立即启动,即使第一个请求失败,其他请求也已发送,因此您无法阻止它们被发送。

如果您按顺序运行异步操作并发出一个请求,并且只有一旦获得该响应,则运行下一个请求,然后您可以在发生故障时停止发送任何后续操作。

您问题中的代码是并行启动所有请求,因为arr.map()是同步的(它一次遍历整个数组)。因此,当第一个响应返回时,所有其他请求都已发送,因此您无法停止它们。

您可以通过多种方式对数组中的项进行排序。适用于所有Promise库的一种常见设计模式是使用.reduce()

var arr = [{col1: 1}, {col2: 1}];
arr.reduce(function(p, val) {
    return p.then(function() {
        return indexingFunction(val);
    });
}, Promise.resolve(result)).then(function() {
    // all finished successfully
}, function(err) {
    // finished with err
});

Bluebird还内置了一些用于处理集合的函数:

Promise.map(arr, function(val) {
    return indexingFunction(val);
}, {concurrency: 1}).all().then(function(results) {
    // all results here
}, function(err) {
    // error here
});

仅供参考,您可能还希望看到:ES6 Promises - something like async.each?