Как вложить несколько Promise.all - PullRequest
0 голосов
/ 10 мая 2018

У меня есть несколько массивов обещаний

Каждый массив помещается в Promise.all()

then() каждого Promise.all() добавляет данные к tempObject

Мне нужно установить tempObject в состояние после выполнения then() из всех Promise.all().

Каков наилучший подход (чистый и читаемый код) для достижения этой цели?

ниже мой код

callSomeApis(parameter){
  let tempArray1 = [];
  let tempArray2 = [];
  this.props.dispatch(actions.callApi1(parameter)).then(callApi1Result =>{
    let callApi1ResultArray = callApi1Result.data.data;
    let PromiseArr1 = callApi1ResultArray.map((callApi1ResultArrayItem) => {
      return this.props.dispatch(actions.callApi2(callApi1ResultArrayItem.itemId));
    });
    let PromiseArr2 = callApi1ResultArray.map((callApi1ResultArrayItem) => {
      return this.props.dispatch(actions.callApi3(callApi1ResultArrayItem.itemId,parameter));
    });
    let PromiseArr3 = callApi1ResultArray.map((callApi1ResultArrayItem) => {
      return this.props.dispatch(actions.callApi4(callApi1ResultArrayItem.itemId));
    });
    Promise.all(PromiseArr1).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 => {
        return{
          stateKey1: {
            ...prevState.stateKey1,
            innerStateKey1: {
              ...prevState.stateKey1.innerStateKey1,
              list: tempArray2
            }
          }
        }
      });
    });
    Promise.all(PromiseArr2).then((callApi3Result) => {
      callApi3Result.map((callApi3ResultItem, index) => {
        callApi1ResultArray[index].api3Result = callApi3ResultItem.data.data;
      });
    });
    Promise.all(PromiseArr3).then(callApi4Result => {
      callApi4Result.map((callApi4ResultItem,index) => {
        callApi1ResultArray[index].api4Result =  callApi4ResultItem.data.data;
      });
    });
    /**need to call this after the thens of  PromiseArr1, PromiseArr2 and PromiseArr3 are done executing*/
    this.setState({
      stateKey2:callApi1ResultArray
    })
    /** */
  })
}

Ответы [ 3 ]

0 голосов
/ 10 мая 2018

Если вы можете, вы также можете использовать async / await

async function (...) {
  const r1 = await Promise.all(...);
  // do something with r1
  const r2 = await Promise.all(...);
  // ...
}

и так далее.Убедитесь, что вы используете Promise.all для действий, которые могут быть распараллелены (которые также возвращают Promise).

Я считаю, что async / await действительно убирает некоторые неприятные Promise цепочки / вложение и очень помогает с читабельностью.

0 голосов
/ 10 мая 2018

Promise.prototype.then само по себе возвращает обещание.Таким образом, вы можете законно и аккуратно обернуть все это в супер Promise.all как для лучшей производительности, так и для размера кода.также рассмотрим "use strict"; и локализацию глобальных переменных и поиск свойств.

{ // 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
                })
                /** */
            );
        })
    }
}

Кроме того, ответственно используйте then и finally для максимальной производительности.Используйте then, если вам требуется возвращаемое значение, и finally, если нет.Кроме того, используйте блок-операторы в функциях стрелок соответствующим образом для максимальной читабельности кода (функции стрелок иногда не нуждаются в них).Наконец, иногда попробуйте повторно использовать объекты для повышения производительности.

0 голосов
/ 10 мая 2018

Promise.all возвращает обещание, поэтому вы можете сделать:

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

Если все ваши обещания очень похожи, вы можете очистить их, создав массив и сопоставив его с обещаниями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...