Javascript 如何使用Promise.all分解动态数量的异步调用的结果

Javascript 如何使用Promise.all分解动态数量的异步调用的结果,javascript,es6-promise,Javascript,Es6 Promise,我需要通过Promise.all>并行进行未知数量的异步调用。类似于此: let externalCalls = [call1()]; if (someCondition1) { externalCalls.push(call2()); } if (someCondition2) { externalCalls.push(call3()); } 然后,externalCalls将被传递给Promise.all,以便它们可以并行运行 理想情况下,我希望使用结果的分解结构,以便我可以按名称

我需要通过
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
会在那里。因此,我想定义调用
wait Promise的
const
结果。所有
动态地具有正确的属性,这可能吗?还是说我一直在使用一个长度未知的通用结果数组,然后必须检查结果中的每个项目,看看是哪个调用产生了它?

没有直接的方法知道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..];
 returnedData = { 
    'call1': { call1 related data},
    'call2': { call2 related data},
    'call3': { call3 related data},
}
在promise.all response中,您可以像这样检查每个返回响应的源”

当您返回控制台时,数据将得到如下结果:

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..];
 returnedData = { 
    'call1': { call1 related data},
    'call2': { call2 related data},
    'call3': { call3 related data},
}

一方面,您已经知道哪些调用是基于
someCondition1
等的
.push()
外部调用的

但也许最好以不同的方式构建
externalCalls
,使其始终具有相同的长度:

const conditions=[true,someCondition1等]
const calls=[call1、call2等]
const externalCalls=conditions.map(
(c,i)=>c?调用[i]():Promise.resolve(null))
const[result1、result2等]=等待承诺.all(外部调用)

如果someCondition1为false,则不推送任何内容,如果someCondition2为true,则推送call3(),因此您应该期望call3位于返回数组的第二项中。 因此,您可以只为没有值的调用返回undefined,将调用保留在具有同步索引的数组中

让someCondition1=false;
让someCondition2=true;
让call1=()=>Promise.resolve(“你好”);
让call2=()=>Promise.resolve(“世界”);
让call3=()=>Promise.resolve(“:”);
让外部调用=[
call1(),
someCondition1?call2():未定义,
someCondition2?call3():未定义
];
异步函数解析调用(调用){
const[call1,call2,call3]=等待承诺。全部(调用);
console.log(“call1:”,call1);
console.log(“call2:”,call2);
console.log(“call3:”,call3);
}
解析调用(外部调用);
我的代码

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'}

const[call1,…rest]
也许
const[call1,…restCalls]
?它应该可以正常工作,但也有可能call2、call3未定义@ᆼᆺᆼ 是的,这允许在call1之后有动态数量的元素,但是你能详细说明我将如何使用rest参数来确定进行了哪些调用吗?@George不幸的是,它不起作用。假设我进行了call1和call3,如果results const定义为
[call1,call2,call3]
,call3的结果实际上在
call2
变量中,
call3
是未定义的。是的,我知道这种方法,但我的问题是是否可以动态生成解构语句。谢谢!谢谢@George。你和ᆼᆺᆼ 两人提出的方法基本相同,但由于他们以7分钟的优势击败了你,我将接受他们的答案,但我对他们都投了更高的票