다른 사람들이 말했듯이 데이터베이스 코드는 비동기식입니다. 즉, 루프 내의 콜백은 나중에 루프가 이미 완료된 후에 언젠가 나중에 호출됩니다. 비동기 루프를 프로그래밍하는 방법에는 여러 가지가 있습니다. 귀하의 경우에는 데이터베이스의 약속 인터페이스로 이동 한 다음 약속을 사용하여 여러 데이터베이스 호출을 조정하는 것이 가장 좋습니다. 이 같은이 작업을 수행 할 수 있습니다
는
Promise.all(riders.map(rider => {
return Rider.findOne({_id: rider}).exec();
})).then(foundRiders => {
// all found riders here
}).catch(err => {
// error here
});
이 쿼리를 실행하고 약속을 반환 몽구스 데이터베이스에 .exec()
인터페이스를 사용합니다. 그런 다음 riders.map() builds and returns an array of these promises. Then,
Promise.all() monitors all the promises in the array and calls
.then() when they are all done or
.catch()`오류가있는 경우. 데이터베이스에서 발견되지 않은 모든 라이더를 무시하는 것이 아니라 오류로 중단하려면
, 당신은이 작업을 수행 할 수 있습니다
Promise.all(riders.map(rider => {
return Rider.findOne({_id: rider}).exec().catch(err => {
// convert error to null result in resolved array
return null;
});
})).then(foundRiders => {
foundRiders = foundRiders.filter(rider => rider !== null);
console.log(founderRiders);
}).catch(err => {
// handle error here
});
은 무엇을 설명하기 위해 여기서, 이것은 모든 데이터베이스 콜백이 완료되었을 때 (수동 카운터로)보다 오래된 구식 모니터링 방법입니다 (수동 카운터로) :
riders.forEach(function(rider){
let cntr = 0;
Rider.findOne({_id: rider}, function(err, foundRider){
++cntr;
if(err){
console.log("program tried to look up rider for the forEach loop finalizing the results, but could not find");
} else {
foundRiders.push(foundRider);
}
// if all DB requests are done here
if (cntr === riders.length) {
// put code here that wants to process the finished foundRiders
console.log(foundRiders);
}
});
});
여러 비동기 요청을 추적하는 카운터를 유지 사업은 Promise.all()
내장되어 것입니다. 위의
코드는 당신이 당신의 코드를 병렬화하고 시간을 절약하기 위해 함께 쿼리를 실행하려는 것으로 가정합니다. 쿼리를 직렬화하려는 경우 루프를 사용하여 ES6에서 await
을 사용하여 각 결과에 대해 루프를 "대기"하게 만들 수 있습니다 (이렇게하면 작업 속도가 느려질 수 있습니다). 여기에 당신이 할 것입니다 방법은 다음과 같습니다 당신이 다른 언어로 사용할 수 있습니다처럼 더 동기 코드처럼이 보이지만, 여전히 비동기 개념을 사용하고 있는지,
async function lookForRiders(riders) {
let foundRiders = [];
for (let rider of riders) {
try {
let found = await Rider.findOne({_id: rider}).exec();
foundRiders.push(found);
} catch(e) {
console.log(`did not find rider ${rider} in database`);
}
}
console.log(foundRiders);
return foundRiders;
}
lookForRiders(riders).then(foundRiders => {
// process results here
}).catch(err => {
// process error here
});
참고하고 lookForRiders()
기능은 아직 약속을 반환 결과는 .then()
입니다. 이것은 비동기 코드의 일부 유형을 작성하기 쉽게 만드는 Javascript의 새로운 기능입니다.
비동기이므로 쿼리가 완료되기 전에 console.log가 호출됩니다. 그렇기 때문에 콜백 함수 – ztadic91
'console.log (foundRiders);가'Rider.findOne'가 비동기 적으로 실행될 때 실행되기 전에 실행됩니다. – vibhor1997a
....... 왜 안되니까!또한 nodejs는 비동기입니다. – wrangler