2012-05-04 39 views
5

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

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

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

+0

使用async:'user_collection的工作版本。findOne({ \t \t \t \t _id:用户id \t \t \t},功能(错误,用户){ \t \t \t \t如果(误差) \t \t \t \t \t回调(误差) \t \t \t \t否则{ \t \t \t \t \t async.forEach(user.contac ts,function(contact,callback){ \t \t \t \t \t \t console.log(contact); \t \t \t \t \t \t如果(contact.accepted == '真'){ \t \t \t \t \t \t \t user_collection.findOne({ \t \t \t \t \t \t \t \t _id:contact.contactId \t \t \t \t \t \t \t},fu nction(误差,接触){ \t \t \t \t \t \t \t \t result.push(接触); \t \t \t \t \t \t \t \t callback(); \t \t \t \t \t \t \t}) \t \t \t \t \t \t} \t \t \t \t \t},函数(误差){回调(错误,结果)}) \t \t \t \t} \t \t \t} );' – johnny

回答

0

随着Async.js的V1.5.2单元测试,这是each

each(arr, iterator, [callback]) 

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

1

使用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(); 
    } 
    }); 
}); 

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

More information

迈克尔。