问题
Code without any handling:
for (i=0; i<dbImgCount; i++){
(function(i) {
imgDownload(FolderPath[i].FolderPath, function (next){
var url = FolderPath[i].FolderPath;
const img2 = cv.imread(imgDownload.Filename);
match({url,
img1,
img2,
detector: new cv.ORBDetector(),
matchFunc: cv.matchBruteForceHamming,
});
})
})(i);
}
In the above code, imgDownload
is an async function which will download image, match
will match features of downloaded image with another image. Need to execute a function after this for-loop
.
How to restructure this code, using Promise
or async-await
, so that each call to asynchronous function is waited for and only after completing the for-loop
, flow continues?
Edited the code with async-await
:
FolderPath.forEach(FolderPath => {
(async function () {
var filename = await imgDownload(FolderPath.FolderPath);
var url = FolderPath.FolderPath;
const img2 = cv.imread(filename);
imgs = await match({url,
img1,
img2,
detector: new cv.ORBDetector(),
matchFunc: cv.matchBruteForceHamming,
});
})();
});
function someFunction(){
console.log("After forEach");
}
How to execute someFunction
only after forEach
?
回答1:
With your last update, although you have used async-await
inside for-loop
, but that did't stoped your synchronous flow.
I'm assuming your imgDownload
and match
functions are returning promise.
Then new Code will be:
(async function () {
// Next loop won't be executing without completing last.
for (i = 0; i < FolderPath.length; i++) {
var filename = await imgDownload(FolderPath[i].FolderPath);
var url = FolderPath[i].FolderPath;
const img2 = cv.imread(filename);
imgs = await match({url,
img1,
img2,
detector: new cv.ORBDetector(),
matchFunc: cv.matchBruteForceHamming,
});
}
// Now will wait for for-loop to end
function someFunction(){
console.log("After forEach");
}
// End of async-await
})();
Here's a small sample example:
(async function () {
for (i=0; i<5; i++) {
x = await main();
console.log(x, i);
}
console.log("Finally");
})();
// asynchronous main function
function main() {
return new Promise( (resolve, reject) => {
setTimeout(()=> { resolve('Done'); }, 5000)
});
}
回答2:
Thanks everyone for the comments.
(async function () {
for (i = 0; i < FolderPath.length; i++) {
var filename = await imgDownload(FolderPath[i].FolderPath);
var url = FolderPath[i].FolderPath;
const img2 = cv.imread(filename);
imgs = await match({url,
img1,
img2,
detector: new cv.ORBDetector(),
matchFunc: cv.matchBruteForceHamming,
});
}
console.log("After forEach");
})();
This is working - "After forEach"
displays only after for loop.
When using forEach
as mentioned in the answer above.
(async function () {
// Next loop won't be executing without completing last.
FolderPath.forEach(FolderPath => {
var filename = await imgDownload(FolderPath.FolderPath);
var url = FolderPath.FolderPath;
const img2 = cv.imread(filename);
imgs = await match({url,
img1,
img2,
detector: new cv.ORBDetector(),
matchFunc: cv.matchBruteForceHamming,
});
});
// Now will wait for for-loop to end
function someFunction(){
console.log("After forEach");
}
// End of async-await
})();
Output is - SyntaxError: await is only valid in async function
.
I think await
keyword won't be in scope of async
function, when it comes under forEach
, that should be the reason.
来源:https://stackoverflow.com/questions/52276621/how-to-wait-for-multiple-asynchronous-calls-from-for-loop