如何在Angular9中使用Promise.all进行两个api调用?

问题描述

我使用Promise.all进行api调用,如下所示:

    Promise.all(this.hostName.slice(0,this.Id.length).map((hostName) => {
        return this.serviceC.status(hostName)
            .then(res => {
                return new Promise((resolve,reject) => {
                    const oretry: ORInterface = {
                        oQid: res.rows[0].qid,reason: this.reason
                    };
                    this.serviceB.retry(oretry).subscribe(resolve);
                });
            });
    }))
.then(() => {
        this.dialog.close();
    })
        .catch(err => {
            console.log(err);
        });

上面的代码工作正常。 现在,我想在成功完成this.serviceB.retry(oretry)之后再进行一次api调用。 第二个api是this.serviceB.createDbEntry(sentry)sentry如下所示:

                    const sretry: SDInterface = {
                        hostName,Id: this.Id.slice(0,this.Id.length),reason: this.reason
                    };

而且,我正在执行以下操作

    Promise.all(this.hostName.slice(0,reason: this.reason
                    };
                    const sretry: SDInterface = {
                        hostName,reason: this.reason
                    };
                    this.serviceB.retry(oretry).subscribe(resolve);
                    this.serviceB.createDbEntry(sentry).subscribe(resolve);
                });
            });
    }))
.then(() => {
        this.dialog.close();
    })
        .catch(err => {
            console.log(err);
        });

上面的代码给出了错误

error: "SequelizeValidationError: string violation: Id cannot be an array or an object"

似乎没有为每个Id

调用第二个api

解决方法

promise.all在数组中接受输入并在数组中给出响应,

创建2个函数,每个函数都带有异步逻辑,并返回一个承诺,

说funcA和funcB,然后在下面使用它们来仿效地调用它们

Promise.all([funcA(this.hostName),funcB(this.id)])
    .then(respones => {
        console.log(responses[0]); //return value for funcA
        console.log(responses[1]); //return value for funcB
    })
    .catch(err => console.log(err));

我假设您的函数逻辑是正确的,我只是从您的问题中粘贴并给出了结构

const funcA = (hostName) => {
hostName.slice(0,this.Id.length).map((hostName) => {
    return this.serviceC.status(hostName)
        .then(res => {
            return new Promise((resolve,reject) => {
                const oretry: ORInterface = {
                    oQid: res.rows[0].qid,reason: this.reason
                };
                this.serviceB.retry(oretry).subscribe(resolve);
            });
        });
    });
}


const funcB = (Id) => {
Id.slice(0,this.Id.length).map(id => {
                return new Promise((resolve,reject) => {
                    const sretry: SDInterface = {
                        hostName,Id: id,reason: this.reason
                    };

                    this.serviceB.createDbEntry(sentry).subscribe(resolve);
                });
            })
}
,

您可能想看看forkJoin

import { Observable,forkJoin } from 'rxjs';

然后

ngOnInit() {
    let one = this.http.get('some/api/1') //some observable;
    let two = this.http.get('some/api/2') // another observable;

    forkJoin([one,tow]).subscribe(response => {
     // results[0] is our one call
     // results[1] is our second call
     let var1 = response[1];
     let var2 = response[0];
    }/*,error => { in case error handler } */); 
}
,

再次使用Promise.all()会更好吗?

Promise.all(this.hostName.slice(0,reason: this.reason
                };
                this.serviceB.retry(oretry).subscribe(resolve);
            });
        })
        .then(() => {
            return Promise.all(this.Id.slice(0,reason: this.reason
                    };

                    this.serviceB.createDbEntry(sentry).subscribe(resolve);
                });
            })
        });
}))
    .then(() => {
        this.dialog.close();
    })
    .catch(err => {
        console.log(err);
    });

使用toPromise()将使代码更简洁。

Promise.all(this.hostName.slice(0,this.Id.length).map((hostName) => {
    return this.serviceC.status(hostName)
        .then(res => {
            const oretry: ORInterface = {
                oQid: res.rows[0].qid,reason: this.reason
            };
            return this.serviceB.retry(oretry).toPromise();
        })
        .then(() => {
            return Promise.all(this.Id.slice(0,this.Id.length).map(id => {
                const sretry: SDInterface = {
                    hostName,reason: this.reason
                };

                this.serviceB.createDbEntry(sentry).toPromise();
            })
        });
}))
    .then(() => {
        this.dialog.close();
    })
    .catch(err => {
        console.log(err);
    });

,

使用CombineLatest,在Angular中,我们使用RxJ而不是Promise。

combineLatest(
  [this.http.get('call1'),this.http.get('call2')]
).subscribe(([result1,result2]) => {
  // do stuff with result1 and result2
});