【问题标题】:How to correctly use forkJoin and switchMap with Promise to call two apis?如何正确使用 forkJoin 和 switchMap with Promise 调用两个 api?
【发布时间】:2020-08-27 19:45:09
【问题描述】:

我正在Angular 9 中进行 api 调用,如下所示:

import {SubSink} from 'subsink';
...
...
async clickButton() {
    for (let i = 0; i < this.Id.length; i++) {
        const hostId = await this.serviceA.Status(this.hostName[i]);
        this.subs.sink = this.serviceB.createDbEntry(hostId))
            .subscribe(s => {
                if (i === this.Id.length - 1) {
                    this.dialog.close();
                }
            });
    }
}

这里this.Id的类型是any

现在我想在成功完成this.serviceB.createDbEntry(hostId)) 后再次调用this.serviceC.runRetry(hostId) 而且,我通过添加forkJoin 来做到这一点,如下所示:

import {forkJoin} from 'rxjs';
import {switchMap} from 'rxjs/operators';

forkJoin(this.hostName.slice(0, this.Id.length).map(hostName => {
  return this.serviceA.Status(hostName).pipe(
    switchMap(hostId => this.serviceB.createDbEntry(hostId).pipe(map((dbEntry) => ({dbEntry, hostId})))),
    switchMap(resp => this.serviceC.runEntry(resp.hostId))
  )
})).subscribe(() => this.dialog.close());

serviceA Status 的实现如下:

public status<T>(host: string) {
    const hostString = host.toString();
    const Url = `${this.api}/${hostString}`;
    const headers = new HttpHeaders();
    headers.append('Content-Type', 'application/json');
    headers.append('Accept', 'application/json');

    return this.http.get<rData<T>>(Url).toPromise();
}

我收到如下警告:

forkJoin Deprecated symbol used, consult docs for better alternative deprecated export function forkJoin<any>( sources: any):Observable<unknown[]>

我也收到一个错误: TS2339: Property 'pipe' does not exist on type 'Promise &gt;'.

【问题讨论】:

  • 能否展示一下 serviceA.Status 的实现?看起来它不会返回 Observable。你究竟从哪里导入forkJoin? 'rxjs'?
  • 你可以将 promise 返回给 switchMap,但你不能在不使用 from 的情况下通过管道传递它们
  • 我已经更新了我的问题。你能提供一个有效的答案吗?我不需要使用forkJoin 并打开其他方法

标签: javascript node.js angular angular-material fork-join


【解决方案1】:

这里:

const hostId = await this.serviceA.Status(this.hostName[i]);

return this.serviceA.Status(hostName).pipe( //...

在第一行中,您将serviceA.Status() 视为一个承诺。在第二个中,您将其视为可观察的。我假设第一个是正确的(来自错误消息)。快速修复:使用 from 运算符将 promise 转换为 observable。 很好 修复:不要将 promise 范式与 RxJS 范式混合,坚持一个(最好坚持 Rx),否则它有可能变得非常混乱。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多