【问题标题】:Merge promise with observable将 promise 与 observable 合并
【发布时间】:2018-12-14 10:17:08
【问题描述】:

这是我的服务的摘录,我希望 getIssuesmetod 返回 observable,而不是承诺解析为 observable,因为它看起来更干净。我相信有办法,我对此有点太陌生了。

import { Injectable } from '@angular/core'; (...)

@Injectable({ providedIn: 'root', })
export class IssueService {
    private users!: Promise<Map<number, Users>;
    constructor(private http: HttpClient, private userService: UserService) {
        this.users = this.userService.getUsers()
    }

    getIssues() {
        return this.users.then(users => {
            return this.http.get<Iissue[]>(URL, OPTIONS).pipe(
                map(issues => new Issue(issue, users)),
            );
        });
    }
}

【问题讨论】:

标签: angular rxjs rxjs6


【解决方案1】:

最简单的方法是用Observable.from() 包装一个promise,让它遵守Observable 接口。但这不会改变它的热/冷,并可能导致意外行为。

Observables(默认)是惰性的,只有在您订阅它们后才会开始运行。承诺是急切的,将立即开始运行。这可能会导致难以调试的情况,因为您的 observalified-promise 可能会运行并完成超出您的 observable 的范围。

要解决此问题,您可以使用Observable.defer(() =&gt; myPromise()),这样您的承诺只会在订阅 Observable.defer 后才会被调用(并开始运行)。

【讨论】:

  • 很好的解释,我有点喜欢承诺立即运行的可能性,我什至想将承诺作为服务属性,以便尽快运行,我想我可能想切换 http使用 websocket 之类的调用...
【解决方案2】:

这样的功能会起作用:

getIssues() {
  return mergeMap(val =>
    fromPromise(myPromise(val))
  )
}

【讨论】:

  • 我如何将它与 observable 连接起来?我需要在可观察对象上使用地图内的值。
【解决方案3】:

@Wandrille 展示了如何从 Promise 中获取 observable。

您也可以使用“from()”,它也应该适用于 Promises。 现在你可以使用所有的 rxjs 魔法了。

在您的情况下,您希望从一个流(promise)切换到另一个流(htt.get)。因此,我将使用“switchMap”,然后使用“map”以您希望的格式获取日期。

getIssues():Observable<Issue>{
    return from(this.users).pipe(
        switchMap((users:Map<number, Users>) => this.http.get(URL,OPTIONS) ),
        map( (issues: IIssue[]): Issue => new Issue(issue,users) )
    )
}

热烈的问候

【讨论】:

    猜你喜欢
    • 2020-02-02
    • 1970-01-01
    • 1970-01-01
    • 2022-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    相关资源
    最近更新 更多