我想知道我如何并行地做动态获取请求,我一直在尝试这样做12个小时,我无法弄清楚,我在谷歌和StackOverflow上到处看,我真的很累。
for (const fileindex of filelist) {
let dcmFilename = `slice_${fileindex}.dcm`
slices.push( {index:fileindex, filename:dcmFilename} )
fd.append(dcmFilename, files[fileindex], dcmFilename);
fd.append('slices', JSON.stringify(slices));
loopcount += 1
if (filecount == 24 || loopcount == filelist.length){
if (cursorPos !== false) {
let scaleFactor = Tegaki.scaleFactor;
cursorPos.x = parseInt(cursorPos.x / scaleFactor);
cursorPos.y = parseInt(cursorPos.y / scaleFactor);
fd.append('x', cursorPos.x);
fd.append('y', cursorPos.y)
}
// Get layer id from index
if (index !== -1) {
type = this.layerTypes[index]['id']
}
// switch mode from heuristic to pytorch vertebrae for vertebral bone
if (type === 'vertebral-bone' ){
mode='PyTorch-Vertebrae'
}
// Post to endpoint
let domain = window.location.origin.replace(':8080', ':5000')
let list = await fetch(`${domain}/segment?mode=${mode}&type=${type}`, { method: 'POST', body: fd })
let result = await list.json()
// do something with result
// finish then continue the loop and create new body and send a new request
// clear formdata and continue loop
fd = new FormData()
}
我有以下fetch请求,我发送,其中的主体是为每个请求生成的,它从来都不是相同的主体,主体是由函数动态生成的。是否有一种方法可以一次发送所有请求,然后等待它们返回响应,然后继续执行其余的代码?
您可以使用带有async
回调的filelist.map()
来代替包含await
的for/of
循环。
由于.map()
只是盲目迭代数组而不等待任何返回的承诺,它将返回.map()
调用的所有async
回调的承诺数组。这些承诺最初将无法实现,fetch()
的所有操作都将"在飞行中"。同时。然后,您可以在返回的承诺数组上使用await Promise.all(...)
来知道它们何时全部完成:
await Promise.all(filelist.map(async fileindex => {
let dcmFilename = `slice_${fileindex}.dcm`
slices.push({ index: fileindex, filename: dcmFilename })
fd.append(dcmFilename, files[fileindex], dcmFilename);
fd.append('slices', JSON.stringify(slices));
loopcount += 1
if (filecount == 24 || loopcount == filelist.length) {
if (cursorPos !== false) {
let scaleFactor = Tegaki.scaleFactor;
cursorPos.x = parseInt(cursorPos.x / scaleFactor);
cursorPos.y = parseInt(cursorPos.y / scaleFactor);
fd.append('x', cursorPos.x);
fd.append('y', cursorPos.y)
}
// Get layer id from index
if (index !== -1) {
type = this.layerTypes[index]['id']
}
// switch mode from heuristic to pytorch vertebrae for vertebral bone
if (type === 'vertebral-bone') {
mode = 'PyTorch-Vertebrae'
}
// Post to endpoint
let domain = window.location.origin.replace(':8080', ':5000')
let list = await fetch(`${domain}/segment?mode=${mode}&type=${type}`, { method: 'POST', body: fd })
let result = await list.json()
// do something with result
// finish then continue the loop and create new body and send a new request
}
}));
注意# 1:由于现在并行运行多个获取操作,因此处理其结果的任何代码都不能共享变量。这段代码中有几个变量没有显示它们的声明。这些声明可能应该与let
或const
一起在这个循环中,所以每次循环迭代都有一个新变量,除非变量显式地应该在迭代中累积,否则你不会在迭代中共享变量。该循环中没有局部声明的可疑变量是filecount
、loopcount
、cursorPos
、index
、mode
、fd
和type
,它们可能受到并行操作的影响。您没有在这里显示整个执行上下文,因此我们无法看到足够的内容来对这些内容提出完整的建议。
注意# 2:包含此if (filecount == 24 || loopcount == filelist.length)
的代码看起来可能容易出现问题。如果您试图在所有迭代完成后运行一些代码,那么最好在Promise.all()
之后运行该代码,而不是试图检测最后一次迭代何时完成。请记住,您的迭代现在不必按顺序进行,因为您正在并行地运行它们。它们将按顺序发射,但不一定按顺序完成。