简体   繁体   中英

Node JS Array, Foreach, Mongoose, Synchronous

I'm not that experienced with node js yet , but i'm learning.

So my issue. Example: I have a small app with mongoose and async modules. In mongodb in a user collection i have 1 user with a field balance = 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)
});

And i'm receiving such result

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

So basically foreach asynchronously is invoking async.waterfall . My question how to do foreach Synchronously item by item, i have tried each, forEach, eachSeries , with and without Promises. Need to get such result at the end

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

Thank You

The problem is where the final callback got called. You need to call cb() inside of waterfall's final callback, not outside:

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

});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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