>我有一个函数,可以在 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);
}
}