使用 $q.all 在 promise 中调用 promise

calling a promise within a promise , with $q.all

我有多个 api 可以并行 运行 的请求。

getlocations、getstates、get territory 可以并行请求。然而,一旦我从 getstates() 调用中获得状态列表,我需要为每个单独的状态发出 api 请求并解析状态对象。

这是我到目前为止的代码,可以这样调用承诺中的承诺吗?

  getAllLocations() {
    //make a promise call for all here .
    var promise = [];
    //first prmise
    promise.push(this.getAllLocations(Id).then(
        (locationsData) => {
            this.locations = locationsData;
        }));
    //second promise
    promise.push(this.getAllStates(Id).then(
        (resp) => {
            this.states = resp.data;
            //for each state , need to make an api call and add to the state info
            angular.forEach(this.states, function(state){
                var nodeId = state.Id;
                this.getStateSummary(nodeId).then((resp) => {
                    state.healthStatus = resp.data.operationalStatus;
                });
            },this)
        }));
    //third promise
    promise.push(this.getAllterritories(Id).then(
        (resp) => {
            this.territories = resp.data;
        }));
    //after all promises parse teh location data
    $q.all(promise).then(() => {
        for (var i = 0; i < this.locations.length; i++) {
            //do something with with location here
        }
        this.gridData = this.locations;
    });
}

如果不是,调用 getStatesummary() 的最佳方法是什么?

您可以使用 promise 链 一个接一个地发送 catch promise

 getAllLocations() {
     //make a promise call for all here .
     var promise = [];
     //first prmise
     this.getAllLocations(Id)
         .then(
             (locationsData) => {
                 this.locations = locationsData;
                 promise.push(this.locations);

                 return this.getAllStates(Id)
             }).then(
             (resp) => {
                 this.states = resp;
                 //for each state , need to make an api call and add to the state info
                 angular.forEach(this.states, function(state) {
                     var nodeId = state.Id;
                     return this.getStateSummary(nodeId);
                 }, this)
                 return this.getAllterritories(Id);
             }).then((resp) => {
             state.healthStatus = resp.data.operationalStatus;
             promise.push(state.healthStatus);
         }).then(
             (resp) => {
                 this.territories = resp.data;
                 promise.push(this.territories);
                 this.callAll(promise)
             })
 }


 callAll(promise) {
     //after all promises parse teh location data
     this.$q.all(promise).then(() => {
         for (var i = 0; i < this.locations.length; i++) {
             //do something with with location here
         }
         this.gridData = this.locations;
     });
 }

我会简化这 3 个承诺(尤其是 1 和 3),以便 this.locations、this.states 和 this.territories 都在 $q.all .then - 你不必这样做,但我认为它使代码更具可读性

接下来,将所有 3 个承诺分配给一个变量(下面代码中的 p1、p2、p3)

下一个问题正在等待所有状态 API 调用完成 - 那里需要另一个 $q.all

总之,再加上一点额外的 ES6 优势,您将获得

getAllLocations() {
    //first prmise
    const p1 = this.getAllLocations(Id);
    //second promise
    const p2 = this.getAllStates(Id).then(resp => 
        //for each state , need to make an api call and add to the state info
        $q.all(resp.map(state => this.getStateSummary(state.Id).then(resp => state.healthStatus = resp.data.operationalStatus)))
        .then(() => resp) // so we return data for this.states
    );
    //third promise
    const p3 = this.getAllterritories(Id).then(resp => resp.data);
    //after all promises parse teh location data
    $q.all([p1, p2, p3]).then(([locations, states, territories]) => {
        this.locations = locations;
        this.states = states;
        this.territories = territories;
        for (var i = 0; i < locations.length; i++) {
            //do something with with location here
        }
        this.gridData = this.locations;
    });
}

如果 getAllStates 承诺 returns 一个对象而不是我假设它是一个数组 - 然后将内部 $q.all 替换为

        $q.all(Object.entries(resp).map(([key, state]) => this.getStateSummary(state.Id).then(resp => state.healthStatus = resp.data.operationalStatus)))

实际上,上面的代码同样适用于 Array 或 Object :p