2012-05-04 4 views
5

node.js의 비동기 특성에 대한 도움이 필요합니다. 데이터베이스에서 데이터를 수집하는 for 루프가 있습니다. "result"는 배열이며 main 함수로 리턴되어야합니다.node.js의 for-loop 완료 후 콜백

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 : userId를 \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, 함수 (연락처, 콜백) { \t \t \t \t \t \t console.log (연락처); \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 경우 : \t \t \t을 contact.contactId \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

답변

10

당신은 당신이 forEach() 방법

forEach(arr, iterator, callback) 
볼 수 있습니다, 그것은 더 일관성있는 코드를 유지하는 데 도움이 https://github.com/caolan/async

비동기 .. 귀하의 경우에는

같은 도우미 라이브러리를 사용하여 고려할 수 있습니다

반복자는 목록의 항목과 완료 될 때의 콜백으로 호출됩니다. Async.js v1.5.2의 예와

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

+0

고마워! 지금 사용하고있어 작동합니다! – johnny

0

위한

지갑 단위 테스트, 그것은 each이다.

each(arr, iterator, [callback]) 

도착 - 배열이 반복 실행.
반복자 (항목, 콜백) - arr의 각 항목에 적용하는 함수입니다.
콜백 (오류) - 선택 사항. 모든 반복기 함수가 끝나거나 오류가 발생하면 호출되는 콜백. ES6는 을 약속 사용

1

는 (약속 라이브러리는 이전 버전의 브라우저에 사용할 수 있습니다) : 동기 실행 (다음 다음 예를 들어 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')) 

프로세스의 모든 비동기 요청없이 보장

프로세스 모든 요청을 "동기"실행이

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

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

(2보다 빠른 1을 마무리 할 수있다) 나는 그 길에 그것을했다

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

마이클.