所以我有一个功能,可以用作从同步可观察流中选择值的简写。
完整功能如下:
export function select<T>(inStream: Observable<T>): T {
let value: T;
race(
inStream,
throwError(
new Error(
select.name + " expects a synchronous stream. Received an asynchronous stream."
)
)
)
.pipe(take(1))
.subscribe(val => {
value = val;
});
return value;
}
它按预期工作,并且如果inStream不同步,则会引发错误,这意味着我要么总是在最新/当前发射中获取值,要么出现错误。
但是,打字稿抱怨在分配值之前使用了该值。我能理解Typescript不够聪明,无法了解如何强制进行同步或发生错误,并且测试表明,当流实际上是同步的时,该值将始终正确设置,否则我们将收到错误。>
那么我应该如何避免这种愚蠢的Typescript-derp?我不太想忽略它,尽管如果没有人提出任何很好的建议,我正在考虑这一点。
无论如何,谢谢!
(演示以按预期方式显示功能,因此我们可以专注于解决打字稿解决方案,而不会因我在使用代码所做的事情而陷入困境:
https://stackblitz.com/edit/rxjs-select-demo?file=index.ts
select在此示例中使用了两次。首先在同步流上获取值。第二次在异步流上并引发错误,并且不返回任何值。完美。)
答案 0 :(得分:0)
因为subscribe
通常预期可以异步使用,所以我认为最干净的解决方案是将其转换为Promise并返回该Promise:
export function select<T>(inStream: Observable<T>): Promise<T> {
return race(
inStream,
throwError(
new Error(
select.name + " expects a synchronous stream. Received an asynchronous stream."
)
)
)
.pipe(take(1))
.toPromise();
}
当然,您还需要在.then
的使用者中称呼await
或select
的承诺。
如果更适合您的用例,您还可以返回observable并使用其方法。
如果/需要调整代码以使其也与异步流一起使用,这还将使代码更具可扩展性。