简体   繁体   English

以可观察的方式合并诺言

[英]Merge promise with observable

Here is extract of my service, I would like getIssues metod to return observable, rather than promise resolving into observable as it would seem so much more clean. 这是我的服务的摘录,我希望getIssues方法返回可观察的,而不是承诺解析为可观察的,因为它看起来要干净得多。 I am confident there is a way, I am just a bit too new to this. 我相信有办法,对此我有点太新了。

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)),
            );
        });
    }
}

The easiest approach is to wrap a promise with Observable.from() to have it adhere to the Observable interface. 最简单的方法是使用Observable.from()包装一个promise,使其遵守Observable接口。 But this does not change its hot/coldness and can lead to unexpected behaviour. 但这不会改变其热度/冷度,并可能导致意外的行为。

Observables are ( by default ) lazy and will only start running once you subscribe to them. Observables( 默认情况下 )是惰性的,并且只有订阅它们后才开始运行。 Promises are eager and will start running immediately. 承诺很热切,将立即开始运行。 This can result in hard to debug conditions because your observalified-promise might run & complete out-of-scope of your observable. 这可能导致难以调试的条件,因为您的可观察性承诺可能​​会运行并完全超出可观察性范围。

To resolve this you can use Observable.defer(() => myPromise()) so your promise will only be invoked (& start running) once the Observable.defer is subscribed to. 要解决此问题,您可以使用Observable.defer(() => myPromise())这样,只有在Observable.defer订阅后,您的诺言才会被调用(并开始运行)。

function like this would work: 这样的功能将工作:

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

@Wandrille showed how to get an observable from a promise. @Wandrille展示了如何从承诺中获得可观察的东西。

You could also use "from()", that should also work with Promises. 您还可以使用“ from()”,它也应与Promises一起使用。 Now you can use all the rxjs magic on it. 现在您可以在其上使用所有rxjs魔术了。

In your case, you want to switch from one stream (the promise) to another stream (the htt.get). 在您的情况下,您想从一个流(promise)切换到另一个流(htt.get)。 Therefor i would use "switchMap" and after that "map" to get the date in the format you wish. 为此,我将使用“ 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) )
    )
}

warm regards 温暖的问候

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM