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 YesPromise\u all=Promise。运行代码不需要all,但需要代码“干净”。干净意味着性能和良好的编码实践。最佳性能优化之一是本地化全局变量,以避免昂贵的对象属性查找,并允许JIST编译器更好地优化代码。此外,“深嵌套”实际上并不是深嵌套,而是深度缩进。然而,我很好奇你所说的““使用严格”;
可以被eslint和es6模块所取代。”我想知道你这是什么意思。“在总是具有严格模式语义的ECMAScript模块中,指令是不必要的。”至于您的其他评论,我想我们必须同意不同意:)