繁体   English   中英

Promise中的同步循环全部

[英]Synchronous loop in Promise all

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

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

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

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

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

不使用await (不在node.js v6.11.2中,但会使这更简单),序列化一堆返回promise的异步操作的经典模式是使用如下的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()结果放入一个数组中,完成后即可访问该数组。

这会将所有对saveInDatabase(item)的调用序列化,等待第一个调用第二个之前,等待第二个调用,然后再调用第三个,等等...

如果saveInDatabase(item)拒绝,则此处的默认实现将停止。 如果你想继续(你没有在你的问题中说),即使它给出了错误,那么你可以添加一个.catch()来将被拒绝的承诺变成一个履行的承诺。


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

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()添加到saveInDatabase() promise链中,将拒绝转换为已解决的promise,其中包含您可以检测到的某些已知值或错误值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM