如何等待来自 for 循环的多个异步调用?
Posted
技术标签:
【中文标题】如何等待来自 for 循环的多个异步调用?【英文标题】:How to wait for multiple asynchronous calls from for loop? 【发布时间】:2019-02-15 23:59:35 【问题描述】:没有任何处理的代码:
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);
在上面的代码中,imgDownload
是一个用于下载图像的async function,match
会将下载图像的特征与另一个图像匹配。在for-loop
之后需要执行一个函数。
如何重构这段代码,使用Promise
或async-await
,使得每次调用异步函数都被等待并且只有在完成for-loop
之后,流程才能继续?
用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");
someFunction
only如何在forEach
之后执行?
【问题讨论】:
imgDownload
支持承诺吗?如果没有,start with that
"这样我就可以在此之后执行回调函数。" - 不,如果你想使用 Promise,你不会在之后调用回调函数这样,您将改为返回匹配的承诺。
我使用了 image-downloader npm 包,它支持 Promise。 npmjs.com/package/image-downloader
好的。您是否查看了their example 并尝试将其应用于您的案例?
使用异步/等待?我该怎么办? var promise1 = new Promise(function(resolve, reject)
resolve('Success!');
);
promise1.then(function(value)
console.log(value);
// 预期输出:“成功!” );
这样使用promise?
【参考方案1】:
在您上次更新时,虽然您在 for-loop
中使用了 async-await
,但这并没有阻止您的同步流程。
我假设您的 imgDownload
和 match
函数正在返回承诺。
那么新代码将是:
(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
)();
这是一个小示例:
(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)
);
【讨论】:
SyntaxError: await is only valid in async function
这将是输出。
await
在 async
函数内【参考方案2】:
感谢大家的cmets。
(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");
)();
这是工作 - "After forEach"
仅在 for 循环后显示。
当使用上面答案中提到的forEach
时。
(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
)();
输出是 - SyntaxError: await is only valid in async function
。
我认为await
关键字不会在async
函数的范围内,当它在forEach
下时,应该是这个原因。
【讨论】:
是的,没注意到,forEach
带有一个callback
函数,这使它超出了async
的范围,因此await
在async
之外使用。
您可以使用for-loop
编辑我的答案,因为它可以解决您的问题。以上是关于如何等待来自 for 循环的多个异步调用?的主要内容,如果未能解决你的问题,请参考以下文章