Javascript 如何嵌套多个承诺

Javascript 如何嵌套多个承诺,javascript,reactjs,es6-promise,Javascript,Reactjs,Es6 Promise,我有很多承诺 每个数组都放在一个Promise.all() 每个Promise.all()的then()将数据添加到tempObject 我需要将tempObject设置为在所有Promise的then()之后的状态。所有()都已执行完毕 实现这一点的最佳方法(干净易读的代码)是什么 下面是我的代码 callsomeapi(参数){ 设tempArray1=[]; 设tempArray2=[]; this.props.dispatch(actions.callApi1(参数))。然后(call

我有很多承诺

每个数组都放在一个
Promise.all()

每个
Promise.all()的
then()
将数据添加到
tempObject

我需要将
tempObject
设置为在所有
Promise的
then()
之后的状态。所有()
都已执行完毕

实现这一点的最佳方法(干净易读的代码)是什么

下面是我的代码

callsomeapi(参数){
设tempArray1=[];
设tempArray2=[];
this.props.dispatch(actions.callApi1(参数))。然后(callApi1Result=>{
让callApi1ResultArray=callApi1Result.data.data;
让PromiseArr1=callApi1ResultArray.map((callApi1ResultArrayItem)=>{
返回此.props.dispatch(actions.callApi2(callApi1ResultArrayItem.itemId));
});
让PromiseArr2=callApi1ResultArray.map((callApi1ResultArrayItem)=>{
返回此.props.dispatch(actions.callApi3(callApi1ResultArrayItem.itemId,参数));
});
让PromiseArr3=callApi1ResultArray.map((callApi1ResultArrayItem)=>{
返回此.props.dispatch(actions.callApi4(callApi1ResultArrayItem.itemId));
});
Promise.all(PromiseArr1)。然后((callApi2Result)=>{
callApi2Result.map((callApi2ResultItem,索引)=>{
callApi1ResultArray[index].api2Details=callApi2ResultItem.data.data[0];
tempArray2.push({id:callApi2ResultItem.data.data[0].id,text:callApi2ResultItem.data.data[0].text});
});
this.setState(prevState=>{
返回{
国家重点1:{
…prevState.stateKey1,
innerStateKey1:{
…prevState.stateKey1.innerStateKey1,
列表:tempArray2
}
}
}
});
});
Promise.all(PromiseArr2)。然后((callApi3Result)=>{
callApi3Result.map((callApi3ResultItem,index)=>{
callApi1ResultArray[index].api3Result=callApi3ResultItem.data.data;
});
});
PromiseArr3.然后(callApi4Result=>{
callApi4Result.map((callApi4ResultItem,index)=>{
callApi1ResultArray[index].api4Result=callApi4ResultItem.data.data;
});
});
/**需要在PromiseArr1、PromiseArr2和PromiseArr3的THEN完成后调用此命令*/
这是我的国家({
stateKey2:callApi1ResultArray
})
/** */
})

}
承诺。all
返回一个承诺,以便您可以执行以下操作:

const p1 = Promise.all(PromiseArr1).then(...);
const p2 = Promise.all(PromiseArr2).then(...);
const p3 = ...
Promise.all([p1, p2, ...]).then(...);

如果所有承诺都非常相似,您可以通过创建一个数组并将其映射到承诺来清理它。

如果可以,您还可以使用
async
/
wait

async function (...) {
  const r1 = await Promise.all(...);
  // do something with r1
  const r2 = await Promise.all(...);
  // ...
}
等等。确保您正在对可以并行化的操作使用
Promise.all
(也返回
Promise


我发现
async
/
await
确实清理了一些讨厌的
Promise
链/嵌套,并且在可读性方面有很大帮助。

Promise.prototype。然后
本身返回一个Promise。因此,您可以合法且干净地将整个内容包装成一个超级
承诺。也要考虑<代码>“使用严格”;代码>和本地化全局和属性查找

{ // avoid global leakage
    "use strict";
    let Promise = self.Promise;
    let Promise_all = Promise.all;
    let tempArray1 = [];
    let tempArray2 = [];
    callSomeApis(parameter){
        tempArray1.length = 0;
        tempArray2.length = 0;
        this.props.dispatch(actions.callApi1(parameter)).then(callApi1Result => {
            let callApi1ResultArray = callApi1Result.data.data;
            Promise_all([
                ////////////////// PromiseArr1 //////////////////
                Promise_all(
                    callApi1ResultArray.map((callApi1ResultArrayItem) => {
                        return this.props.dispatch(actions.callApi2(callApi1ResultArrayItem.itemId));
                    })
                ).then(
                    callApi2Result => {
                        callApi2Result.map((callApi2ResultItem,index) => {
                            callApi1ResultArray[index].api2Details = callApi2ResultItem.data.data[0];
                            tempArray2.push({id: callApi2ResultItem.data.data[0].id, text: callApi2ResultItem.data.data[0].text});
                        });
                        this.setState(prevState => ({
                            stateKey1: {
                                ...prevState.stateKey1,
                                innerStateKey1: {
                                    ...prevState.stateKey1.innerStateKey1,
                                    list: tempArray2
                                }
                            }
                        }));
                    }
                ),
                ////////////////// promiseArr2 //////////////////
                Promise_all(
                    callApi1ResultArray.map((callApi1ResultArrayItem) => {
                        return this.props.dispatch(actions.callApi3(callApi1ResultArrayItem.itemId,parameter));
                    })
                ).then(
                    callApi3Result => {
                        callApi3Result.map((callApi3ResultItem, index) => {
                            callApi1ResultArray[index].api3Result = callApi3ResultItem.data.data;
                        });
                    }
                ),
                ////////////////// PromiseArr3 //////////////////
                Promise_all(
                    callApi1ResultArray.map((callApi1ResultArrayItem) => {
                        return this.props.dispatch(actions.callApi4(callApi1ResultArrayItem.itemId));
                    })
                ).then(
                    callApi4Result => {
                        callApi4Result.map((callApi4ResultItem,index) => {
                            callApi1ResultArray[index].api4Result =  callApi4ResultItem.data.data;
                        });
                    }
                )
            ]).finally(
                /**need to call this after the thens of  PromiseArr1, PromiseArr2 and PromiseArr3 are done executing*/
                this.setState.bind(this, {
                    stateKey2: callApi1ResultArray
                })
                /** */
            );
        })
    }
}

另外,要负责任地使用
然后
最后
,以获得最佳性能。需要返回值时使用
然后使用
,不需要返回值时使用
最后使用
。此外,在arrow函数中适当地使用block语句以获得最大的代码可读性(arrow函数有时不需要它们)。最后,有时尝试重用对象以获得更好的性能。

别忘了查看下面我的帖子。它满足了更多的问题要求。我不是投票人,而是
“严格使用”可以用es6模块的eslint替换,
让Promise\u all=Promise。所有的
等都是毫无意义的,调用在参数中的深度嵌套是令人不愉快的。编码风格通常是主观的;有些人可能更喜欢你的方式,所以最好让询问者来决定。@riwu Yes
Promise\u all=Promise。运行代码不需要all,但需要代码“干净”。干净意味着性能和良好的编码实践。最佳性能优化之一是本地化全局变量,以避免昂贵的对象属性查找,并允许JIST编译器更好地优化代码。此外,“深嵌套”实际上并不是深嵌套,而是深度缩进。然而,我很好奇你所说的“
“使用严格”;
可以被eslint和es6模块所取代。”我想知道你这是什么意思。“在总是具有严格模式语义的ECMAScript模块中,指令是不必要的。”至于您的其他评论,我想我们必须同意不同意:)