Я знаю, что я использовал "ожидание" и "асинхронное" слово в том же смысле, что и не имеет смысла. Но я хотел бы знать, может ли кто-нибудь предложить мне решение моей проблемы.
У меня есть цикл, который выполняется в массиве документов, возвращаемых mongodb. Теперь, в зависимости от некоторой логики, мне нужно удалить определенный документ. Только после того, как я закончу удаление документов, я могу вызвать свой следующий метод. Выглядит примерно так:
mymongodbconnection.find({}).toArray(function(err, documents) {
if (!err && documents.length !== 0) {
documents.forEach(function(document) {
if( someCheckPerformed(document)){
console.log('keeping');
}else{
console.log('removing');
mymongodbconnection.remove({_id:document._id},fun(err,result){});
}
});
notifyAdminAboutChange();
} else {
logger.warn('No existing UA docs to filter');
}
});
Теперь, как вы можете видеть, мне нужно вызвать notifyAdminAboutChange(); только после того, как цикл for завершил итерацию по всем документам и удалил документы, которые необходимо удалить.
Мои вопросы:
Используйте обещания - создайте один для каждого документа для удаления, а затем дождитесь их разрешения (используя Promise.all
) перед вызовом вашей функции.
mongodBCollectionInstance.find({}).toArray(function(err, documents) {
if (!err && documents.length !== 0) {
var promises = [];
documents.forEach(function(document) {
if( someCheckPerformed(document)){
console.log('keeping');
}else{
console.log('removing');
promises.push(new Promise(function (fulfill, reject){
mongodBCollectionInstance.remove(
{_id:document._id},
function (err, result) {
fulfill();
});
}))
}
});
Promise.all(promises).then(function () {
notifyAdminAboutChange();
});
} else {
logger.warn('No existing UA docs to filter');
}
});
Я не знаю каких-либо JS-бит рук, чтобы легко закрепить в вашей существующей структуре, но если вы немного измените порядок и оставите свой разум открытым для рекурсивного решения, вы можете достичь желаемого результата:
coll.find({}).toArray((err, docs)=> {
(function checkDoc(i){
if(i >= docs.length) return;
else if(pred(docs[i])) checkDoc(i + 1);
else coll.remove({_id: docs[i]._id}, _=> checkDoc(i + 1));
})(0);
})
Таким образом, документы проверяются по порядку, и следующий документ обрабатывается только тогда, когда текущий полностью обрабатывается.
Promise.all()
. Несколько связанных ответов: Как синхронизировать последовательность обещаний? и асинхронная функция внутри цикла JavaScript для