在nodejs(asynchronous)循环和callback中寻找适当的模式
我已经阅读了几篇文章和文章,但是我不太明白。
我在Mongoose模型中有一段代码,主要负责邀请人们参与项目。 鉴于一些被邀请者,我期待看看他们是否在数据库中,如果没有,我会继续创build它们并更新被邀请者列表中的ID。
jslint抱怨循环,我正在努力与callback(和正确的总体模式,当你有一个循环,与数据库保存callback。显然我想要发生的是循环完全完成,任何新用户都添加到数据库,ID是在原始哈希(受邀者)更新,然后callback发生。
ProjectSchema.methods.invite = function invite(invitees, callback) { var User = mongoose.model('User'); var emails = _.pluck(invitees, 'email'); // loop through invited hash to see if we already have those users in the db User.find({ 'email': { $in: emails}}, function (err, users) { for (var invited = 0; invited < invitees.length; invited++) { var found = false; // logic here to see if they are already users using the users param if (found) { // they are already in the db so do unrelated things. } else { // create new user var User = mongoose.model('User'); var newUser = // set up new user here newUser.save(somecallback?); // update invitees list with id } } callback(err, invitees); }); };
这里有几个问题:
-
你正在for循环中声明局部variables。 这是因为JavaScript有function范围,而不是块范围(variables提升),所以不鼓励。
-
您需要一些方法将您为保存的每个用户所做的asynchronous更改同步到数据库,即等待循环完成。
对于1.,我build议你使用Array.map
,即声明一个函数
function processUser (invited) { // essentially the body of your for loop }
然后调用invitees.map(processUser)
。
2.问题更难:我build议你使用一个提供asynchronous支持的库,比如Q.
要做到这一点,请让processUser
函数返回一个在完成时解决的Q promise,然后使用Q.all
进行同步。 即像这样的东西:
Q.all(invitees.map(processUser)) .then(function (completions) {callback(null,invitees);}, function (err) {callback(err,null);});
包起来 :
// import Q var Q = require('q'); // ... ProjectSchema.methods.invite = function invite(invitees, callback) { var User = mongoose.model('User'); var emails = _.pluck(invitees, 'email'); // loop through invited hash to see if we already have those users in the db function processUser (invited) { var deferredCompletion = Q.defer(); var found = false; // logic here to see if they are already users using the users param if (found) { // they are already in the db so do unrelated things. // ... deferredCompletion.resolve(true); // resolve with some dummy value } else { // create new user var newUser = // set up new user here newUser.save(function (err, user){ if (err) { deferredCompletion.reject(err); } else { // update invitees list with id // ... deferredCompletion.resolve(true); } }); } return deferredCompletion.promise; } Q.all(invitees.map(processUser)) .then(function (completions) { callback(null,invitees); }, function (err) { callback(err,null); }); };
- 如何在Node.js中创build一个API请求响应stream?
- 将asynchronous函数转换为同步函数
- async.times函数不会触发callback
- Node.js请求获取ETIMEDOUT和ESOCKETTIMEDOUT的模块
- Async.jsdevise模式
- Node.js用于循环asynchronous请求
- 如何正确使用node.js中的asynchronous函数的承诺?
- 为什么node.jsasynchronous模块在使用async.eachLimit(array,limit,function,callback)的第一步之后停止?
- 来自child_process的node.js:console.log