我需要通过Promise.all
并行进行未知数量的异步调用。与此类似:
let externalCalls = [call1()];
if (someCondition1) {
externalCalls.push(call2());
}
if (someCondition2) {
externalCalls.push(call3());
}
然后externalCalls
将被传递到Promise.all
,以便它们可以并行运行。
理想情况下,我想对结果进行分解,以便我可以按名称引用结果,即
const [call1, call2, call3] = await Promise.all(externalCalls);
我知道call1
将会一直存在,但是我不知道call2
或call3
是否会在那里。因此,我想定义动态调用const
的{{1}}结果以具有正确的属性,这可能吗?还是我陷入了一个未知长度的通用结果数组,然后必须检查结果中的每个项目以查看是哪个调用产生了它?
答案 0 :(得分:1)
没有直接的方法来了解promise.all的响应来源。
但是您可以向call1,call2,call3的响应中添加更多信息
因此修改后的代码如下:
let call1 = fetch(url).then(data1 => ({...data1, source: 'call1'}));
let call2 = fetch(url).then(data2 => ({...data2, source: 'call2'}));
let call3 = fetch(url).then(data3 => ({...data3, source: 'call3'}));
let externalCalls = [call1, call2, call3, etc..];
以及您的promise.all答复中,您可以像这样检查每个返回的答复的来源。
let returnedData = {};
Promise.all(externalCalls).then(allData => {
for(let data of allData){
returnedData[data.source] = data;
console.log(returnedData);
}
});
,当您控制台返回数据时,将得到类似的内容:
returnedData = {
'call1': { call1 related data},
'call2': { call2 related data},
'call3': { call3 related data},
}
答案 1 :(得分:1)
一方面,您已经知道根据.push()
等externalCalls
到someCondition1
的呼叫了。
但是也许以不同的方式构建externalCalls
更好,因此它总是具有相同的长度:
const conditions = [true, someCondition1, etc]
const calls = [call1, call2, etc]
const externalCalls = conditions.map(
(c, i) => c ? calls[i]() : Promise.resolve(null))
const [result1, result2, etc] = await Promise.all(externalCalls)
答案 2 :(得分:1)
如果someCondition1为false,则不推送任何内容,然后,如果someCondition2为true,则按call3(),因此您应该期望call3在返回数组的第二项中。 因此,您可以只对没有值的调用返回undefined,从而使调用在数组中具有同步索引。
let someCondition1 = false;
let someCondition2 = true;
let call1 = () => Promise.resolve("hello");
let call2 = () => Promise.resolve("world");
let call3 = () => Promise.resolve(":)");
let externalCalls = [
call1(),
someCondition1 ? call2() : undefined,
someCondition2 ? call3() : undefined
];
async function resolveCalls(calls){
const [call1, call2, call3] = await Promise.all(calls);
console.log("call1:", call1);
console.log("call2:", call2);
console.log("call3:", call3);
}
resolveCalls(externalCalls);
答案 3 :(得分:0)
我的代码
const promiseFor1stAPICall = () => {
return new Promise((resolve) => {
return setTimeout(() => {
resolve({ data: "1st api data" });
}, 2000);
});
};
const promiseFor2edAPICall = () => {
return new Promise((resolve) => {
return setTimeout(() => {
resolve({ data: "2ed api data" });
}, 2000);
});
};
const promiseFor3rdAPICall = () => {
return new Promise((resolve) => {
return setTimeout(() => {
resolve({ data: "3rd api data" });
}, 2000);
});
};
const promiseFor4thAPICall = () => {
return new Promise((resolve) => {
return setTimeout(() => {
resolve({ data: "4th api data" });
}, 2000);
});
};
async function destructureFromPromiseAll() {
const promises = [];
promises.length = 4;
const obj = {
condition1: false,
condition2: true,
};
promises[0] = promiseFor1stAPICall();
if (obj.condition1) {
promises[1] = promiseFor2edAPICall();
promises[2] = promiseFor3rdAPICall();
}
if (obj.condition2) {
promises[3] = promiseFor4thAPICall();
}
const data = await Promise.all(promises);
return data;
}
async function log() {
const data = await destructureFromPromiseAll();
const [
firstAPICallRes,
secondAPICallRes,
thirdAPICallRes,
fourthAPICallRes,
] = data;
console.log(
firstAPICallRes,
secondAPICallRes,
thirdAPICallRes,
fourthAPICallRes
);
}
log();
============output===============
{data: '1st api data'}, undefined, undefined, {data: '4th api data'}