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

Javascript 如何使用Promise.all在Angular9中进行两个api调用?,javascript,node.js,angular,promise,angular-promise,Javascript,Node.js,Angular,Promise,Angular Promise,我使用Promise进行api调用。所有如下所示: Promise.all(this.hostName.slice(0, this.Id.length).map((hostName) => { return this.serviceC.status(hostName) .then(res => { return new Promise((resolve, reject) => {

我使用
Promise进行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);
        });
                    const sretry: SDInterface = {
                        hostName,
                        Id: this.Id.slice(0, this.Id.length),
                        reason: this.reason
                    };
上面的代码运行良好。 现在,我想在成功完成
this.serviceB.retry(oretry)
后进行另一个api调用。 第二个api是
this.serviceB.createDbEntry(sentry)
并且
sentry
如下所示:

    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);
        });
                    const sretry: SDInterface = {
                        hostName,
                        Id: this.Id.slice(0, this.Id.length),
                        reason: this.reason
                    };
而且,我正在做的事情如下

    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
                    };
                    const sretry: SDInterface = {
                        hostName,
                        Id: this.Id.slice(0, this.Id.length),
                        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。所有
在数组中获取输入并在数组中给出响应

创建两个函数,每个函数的异步逻辑返回一个承诺

说出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, 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(() => {
            return Promise.all(this.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);
                });
            })
        });
}))
    .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,
                    Id: id,
                    reason: this.reason
                };

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


使用CombineTest,在角度上,我们使用RxJs而不是承诺

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

请更新您的答案,并演示如何在
funcA
中使用
this.hostName.slice(0,this.Id.length)
和在
funcB
中使用
this.Id.slice(0,this.Id.length)
funcB
引发错误
TS2663:找不到名称“hostName”。您的意思是实例成员“this.hostName”吗?
如何将
hostName
funcA
传递到
funcB
funcB
仍在抛出错误
TS2304:找不到name”hostName
我正在尝试使用
toPromise()
但出现错误
TSLint:缺少分号(分号)
通过再添加一个括号,分号错误消失了
…this.serviceB.createDbEntry(sentry.toPromise();})请注意,现在
这个.serviceB.createDbEntry(sentry).toPromise()运行了两次而不是一次。你能检查一下吗?我依赖于
promise
。我可以使用上面的答案中的
toPromise()
使其工作。唯一的问题是
this.serviceB.createDbEntry(sentry.toPromise()运行两次而不是一次。你能检查一下吗?