Node.js与Promise.all等待嵌套的Promise

时间:2018-06-23 00:09:52

标签: javascript node.js promise

我试图在循环之前等待所有数据库调用完成,然后再继续。我将每个调用(它们是promise)添加到一个数组中,然后使用Promise.all()等待所有调用。但是,存在user.increment()似乎没有等待的嵌套数据库调用,例如user.create()Promise.all()。此代码段的输出通常为:

User found, incrementing wins...
Promise.all()
User updated

在嵌套DB调用完成之前,正在运行Promise.all块。我觉得我真的很想念一些东西。

let dbCalls = [];
for(var i = 0; i < users.length; i++){
    let messageUser = users[i];
    //try to find user by id
    dbCalls.push(db.user.findOne({
            where: {
                id: messageUser.id
            }
        }).then(function(user){
            if(user){
                //found user, increment them
                user.increment('wins').then((user) => {
                    console.log('User found, incrementing wins...');
                    user.reload();
                }).then(user => {
                    console.log('User updated')
                    return user;
                });
            } else{
                //user wasn't found, create them
                console.log(`${messageUser.username} was not found, creating user...`);
                db.user.create({
                    username: messageUser.username,
                    id: messageUser.id,
                    wins: 1
                }).then(function(user){
                    console.log('created user');
                    return user;
                });
            }
        }).then(res => {
            return res;
        })
    );
}

Promise.all(dbCalls).then(res =>{
    console.log('Promise.all()' + res);
});

3 个答案:

答案 0 :(得分:2)

您忘记了兑现承诺。因此它们不包含在您的承诺链中

只需将带有数据库承诺的行更改为return user.increment('wins').then((user) => {

答案 1 :(得分:0)

由于您正在运行多个数据库查询,需要一个查询才能在另一个查询之前完成,因此您应该查看NODE.js瀑布调用。它允许使用诺言,您可以设置哪些诺言需要其他人先完成才能发射。

https://www.npmjs.com/package/promise-waterfall

有一个很好的例子

该库甚至可以让您等待返回的值在另一个异步调用中使用。

答案 2 :(得分:0)

您需要链接所有内部承诺,以保证被推送到数组的项是完整链。为了提高可读性,请考虑将Thread.sleepincrement提取到各自的函数中:

create