将 promise 与 observable 合并
Posted
技术标签:
【中文标题】将 promise 与 observable 合并【英文标题】:Merge promise with observable 【发布时间】:2018-12-14 10:17:08 【问题描述】:这是我的服务的摘录,我希望 getIssues
metod 返回 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)),
);
);
【问题讨论】:
为什么不把promise转换成可观察的***.com/questions/39319279/…,然后做一个switchMap呢? 【参考方案1】:最简单的方法是用Observable.from()
包装一个promise,让它遵守Observable 接口。但这不会改变它的热/冷,并可能导致意外行为。
Observables(默认)是惰性的,只有在您订阅它们后才会开始运行。承诺是急切的,将立即开始运行。这可能会导致难以调试的情况,因为您的 observalified-promise 可能会运行并完成超出您的 observable 的范围。
要解决此问题,您可以使用Observable.defer(() => 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) )
)
热烈的问候
【讨论】:
以上是关于将 promise 与 observable 合并的主要内容,如果未能解决你的问题,请参考以下文章
Angular 2:将 Observable 转换为 Promise