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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10448295/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 01:21:04  来源:igfitidea点击:

Callback after for-loop finishes in node.js

javascriptnode.jscallback

提问by johnny

I need some help with the asynchronous nature of node.js. I have a for loop, which collects data from the database. "result" is an array, which should then be returned to the main function.

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

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
            }
        });

How can I ensure that the callback executes after the loop finished?

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

回答by 250R

You might want to consider using helper library like asynchttps://github.com/caolan/async

您可能需要考虑使用像async这样的辅助库https://github.com/caolan/async

It helps keep code more consistent..

它有助于保持代码更一致..

In your case, you can look at the forEach()method

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

forEach(arr, iterator, callback)

The iterator is called with an item from the list and a callback for when it has finished.

使用列表中的一个项目和完成时的回调调用迭代器。

Checkout the unit tests for examples

查看单元测试以获取示例

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

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

回答by Michael Horojanski

Using ES6 Promises (a promise library can be used for older browsers):

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

Process all requests guaranteeing synchronous execution (e.g. 1 then 2 then 3)

处理所有保证同步执行的请求(例如 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'))

Process all async requests without "synchronous" execution (2 may finish faster than 1)

在没有“同步”执行的情况下处理所有异步请求(2 可能比 1 完成得更快)

let requests = [1,2,3].map((item) => {
    return new Promise((resolve) => {
      asyncFunction(item, resolve);
    });
})

Promise.all(requests).then(() => console.log('done'));

I did it on that way

我是那样做的

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);
    });

The last example

最后一个例子

function callback (result) { console.log('all done'); }

[1, 2, 3].forEach((item, index, array) => {
  asyncFunction(item, () => {
    if (index === array.length - 1) {
      callback();
    }
  });
});

This does not guarantee that callback will execute after all items are processed. It only guarantees that callback will execute after the very last item is processed.

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

More information

更多信息

Michael.

迈克尔。

回答by Sridhar

With v1.5.2 of Async.js, It is each.

使用 Async.js 的 v1.5.2,它是每个.

each(arr, iterator, [callback])

arr- An array to iterate over.
iterator(item, callback)- A function to apply to each item in arr.
callback(err)- Optional. A callback which is called when all iterator functions have finished, or an error occurs.

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