#javascript #arrays #node.js #mongodb #mongoose
#javascript #массивы #node.js #mongodb #mongoose
Вопрос:
Я еще не настолько разбираюсь в js узлов, но я учусь.
Итак, моя проблема. Пример: у меня есть небольшое приложение с модулями mongoose и async. В 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 , с обещаниями и без них. Нужно получить такой результат в конце
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:
Проблема в том, где был вызван последний обратный вызов. Вам нужно вызвать 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
});