在 node.js 中完成 for 循环后的回调

Callback after for-loop finishes in node.js

本文关键字:循环 回调 for node js      更新时间:2023-09-26

我需要一些关于node.js异步性质的帮助。我有一个 for 循环,它从数据库中收集数据。"result" 是一个数组,然后应该返回到 main 函数。

user_collection.findOne({
            _id : uid
        }, function(error, user) {
            if(error)
                callback(error)
            else {
                for(var j = 0; j < user.contacts.length; j++) {
                    if(user.contacts[j].accepted == 'true') {
                        user_collection.findOne({
                            _id : user.contacts[j].contactId
                        }, function(error, user) {
                            result.push(user);
                        })
                    } 
                }
                callback(null, result);  // This callback executes before the for-loop ends, ofc
            }
        });

如何确保回调在循环完成后执行?

您可能需要考虑使用像异步这样的帮助程序库https://github.com/caolan/async

它有助于保持代码更加一致。

在您的情况下,您可以查看 forEach() 方法

forEach(arr, iterator, callback)

迭代器使用列表中的项和完成时的回调进行调用。

查看单元测试的示例

https://github.com/caolan/async/blob/master/mocha_test/each.js

使用 ES6 承诺(承诺库可用于较旧的浏览器):

处理所有请求,保证同步执行(例如 1 然后 2 然后 3)

function asyncFunction (item, cb) {
  setTimeout(() => {
    console.log('done with', item);
    cb();
  }, 100);
}
let requests = [1, 2, 3].reduce((promiseChain, item) => {
    return promiseChain.then(new Promise((resolve) => {
      asyncFunction(item, resolve);
    }));
}, Promise.resolve());
requests.then(() => console.log('done'))

处理所有异步请求而不进行"同步"执行(2 可能比 1 快完成)

let requests = [1,2,3].map((item) => {
    return new Promise((resolve) => {
      asyncFunction(item, resolve);
    });
})
Promise.all(requests).then(() => console.log('done'));

我就是这样做的

Promise.all(body.schedules.map(function(scheduleId) {
        return new Promise(function(resolve, reject) {
            return scheduleSchema.findOneAndRemove({
                    _id: scheduleId
                })
                .then(function() {
                    logSchema.insert({
                        userId: req.user.id,
                        actId: constants.LOG_SCHEDULE_DELETE.id,
                        extData: scheduleId
                    });
                    resolve();
                })
                .catch(function(err) {
                    reject(err);
                });
        });
    })).then(function() {
        return res.json({
            code: constants.SUCCESS_CODE
        });
    }).catch(function(err) {
        return res.json(constants.DATABASE_ERROR);
    });

最后一个例子

function callback (result) { console.log('all done'); }
[1, 2, 3].forEach((item, index, array) => {
  asyncFunction(item, () => {
    if (index === array.length - 1) {
      callback();
    }
  });
});

这并不能保证在处理完所有项目后将执行回调。它只保证回调将在处理最后一项后执行。

更多信息

迈克尔。

对于 Async.js 的 v1.5.2,它是每个。

each(arr, iterator, [callback])

arr - 要迭代的数组。
迭代器(项,回调) - 应用于 arr 中每个项的函数。
回调(错误) - 可选。当所有迭代器函数完成或发生错误时调用的回调。