Node JS Array,Foreach,Mongoose,Synchronous

时间:2016-10-16 19:30:39

标签: javascript arrays node.js mongodb mongoose

我对节点js没有经验,但我正在学习。

所以我的问题。例: 我有一个带有猫鼬和异步模块的小应用程序。在用户集合的mongodb中,我有1个用户,字段余额= 100。

var arr     = [1,2,3,4];
var userId  = 1;
async.forEachSeries(arr, (item, cb) =>{
    async.waterfall([
        next => {
            users.findById(userId, (err, user) =>{
                if (err) throw err;
                next(null, user)
            });
        },
        (userResult,next) =>{
            var newBalance = userResult.balance - item;
            users.findByIdAndUpdate(userId, {balance:newBalance}, err =>{
                if (err) throw err;
                next(null, userResult, newBalance);
            })
        }

    ],(err, userResult, newBalance) =>{
        console.log(`Old user balance: ${userResult.balance} New user balance: ${newBalance}`);
    });
    cb(null)
});

我收到了这样的结果

Old user balance: 100 New user balance: 98
Old user balance: 100 New user balance: 99
Old user balance: 100 New user balance: 97
Old user balance: 100 New user balance: 96

所以基本上foreach异步调用async.waterfall。我的问题如何逐项实现foreach逐项,我已经尝试了每个,forEach,eachSeries,有和没有Promises。需要在最后得到这样的结果

Old user balance: 100 New user balance: 99
Old user balance: 99 New user balance: 97
Old user balance: 97 New user balance: 94
Old user balance: 94 New user balance: 90

谢谢

1 个答案:

答案 0 :(得分:1)

问题在于调用最终回调的位置。你需要在瀑布的最终回调中调用cb(),而不是在外面:

var arr     = [1,2,3,4];
var userId  = 1;
async.forEachSeries(arr, (item, cb) =>{
  async.waterfall([
    next => {
        users.findById(userId, (err, user) =>{
            if (err) throw err;
            next(null, user)
        });
    },
    (userResult,next) =>{
        var newBalance = userResult.balance - item;
        users.findByIdAndUpdate(userId, {balance:newBalance}, err =>{
            if (err) throw err;
            next(null, userResult, newBalance);
        })
    }

],(err, userResult, newBalance) =>{
    console.log(`Old user balance: ${userResult.balance} New user balance: ${newBalance}`);
    cb(null);   // <<==== call here
});
// cb(null);   // <<==== NOT call here

});