Promise中的同步循环全部

时间:2018-01-29 16:40:51

标签: javascript node.js mongoose promise

我想在代码的一部分中执行同步循环。 saveInDatabase函数检查数据库中是否已存在项标题(字符串)。这就是为什么它不能并行解决,否则条件永远不会适用(并会产生重复)。

Promise.all(arr.map(item => {
     saveInDatabase(item).then((myResult) => ... );
}));

我尝试将此函数封装到单独的promises中,也尝试使用npm包(synchronous.js,sync),但似乎它不适合我的代码。

也许这个解决方案完全是愚蠢的。 您是否认为通过同步循环(例如foreach)替换promise.all更好?问题是我需要每次迭代的结果......

我正在使用Node 6.11.2。你能给我一些处理它的提示吗? 先感谢您。

1 个答案:

答案 0 :(得分:10)

不使用await(不在node.js v6.11.2中,但会使这更简单),序列化一堆返回promise的异步操作的经典模式是使用{{1像这样循环:

reduce()

如果要保存所有结果,可以使用arr.reduce(function(p, item) { return p.then(function() { return saveInDatabase(item).then((myResult) => ... ); }); }, Promise.resolve()).then(function() { // all done here }).catch(function(err) { // error here }); 处理程序将.then(myResult => ...)结果导入到完成后可以访问的数组中。

这将序列化所有对.push()的调用,等待第一个调用完成后再调用第二个调用,等待第二个调用完成后调用第三个调用,等等...... / p>

如果saveInDatabase(item)拒绝,此处的默认实施将停止。如果你想继续(你不在问题中说),即使它出现错误,你也可以添加一个saveInDatabase(item)来将被拒绝的承诺变为履行承诺。

在node.js v7 +中,您可以在常规.catch()循环中使用await

for

如果您可以并行运行所有请求,那么您可以这样做:

async function myFunc() {
    let results = [];
    for (let item of arr) {
        let r = await saveInDatabase(item).then((myResult) => ... );
        results.push(r);
    }
    return results;
}

myFunc().then(function(results) {
    // all done here
}).catch(function(err) {
    // error here
});

在其中任何一项中,如果您不希望它在拒绝后停止,请在您的Promise.all(arr.map(item => { return saveInDatabase(item).then((myResult) => ... ); })).then(function(results) { // all done here }).catch(function(err) { // error here }); 承诺链中添加.catch(),以便将拒绝转化为已解决的承诺您可以检测到的已知值或错误值。