在 Javascript 中为 for 循环中返回承诺的有效方法是什么?



>我有一个函数,可以在 javascript 中的 for 循环后返回一个承诺,由于我是承诺和异步等待的新手,我想知道这是否是在迭代过程中返回承诺的有效方式。这是片段

function addImagesToCanvas(urls){
return new Promise(resolve => {
for(url of urls){
loadImage(url).then(img_element =>{
addImageToCanvas(img_element);
});
}
resolve();
});
}
function displayCanvas(){
$.ajax({
....
success: function(response){
urls = JSON.Parse(response);
addImagesToCanvas(urls).then(() => {
//..Do something
});
}
});
}
Is there a way of re-writting the above code with **async/await** ? Thanks for the comments

绝对不是。您的代码不会等待循环中的承诺解析。

如果你想串联等待它们(一个接一个,每个等待前一个(,那么既然你提到使用async函数和await,你只需在标准逻辑流中编写它,等待每个承诺:

async function addImagesToCanvas(urls){
for (url of urls) {
const img_element = await loadImage(url);
addImageToCanvas(img_element);
}
}

或者当然:

async function addImagesToCanvas(urls){
for (url of urls) {
addImageToCanvas(await loadImage(url));
}
}

如果你想让它们全部并行处理并等待结果,请使用map获取 aaray 的承诺并返回Promise.all创建的承诺并返回其承诺:

function addImagesToCanvas(urls){
return Promise.all(urls.map(url => loadImage(url).then(addImageToCanvas)));
}

或者:

function addImagesToCanvas(urls){
return Promise.all(urls.map(async (url) => {
addImageToCanvas(await loadImage(url);
}));
}

不需要函数本身async,因为它可以直接从Promise.all返回承诺。


旁注:你的代码似乎正在成为我所说的隐式全局的恐怖的牺牲品。您需要声明url.例如,在上面的第一个代码块中:

async function addImagesToCanvas(urls){
for (const url of urls) {
//       ^^^^^----------------------------------------- const or let (or even var, but...I wouldn't)
const img_element = await loadImage(url);
addImageToCanvas(img_element);
}
}

最新更新