我如何知道Observable制作人何时处于异步或同步状态?
同步示例:
apt-get install libffi-dev
另一个异步示例(ngrx Store,请参阅here)
Observable.of([1, 2, 3])
现在是一个明显的异步示例:
this.store.take(1);
我完全理解这是如何工作的,并且一些Observable可以同步和其他异步。我不明白的是我怎么能预先区分出来?例如,生产者有一个明显的界面告诉我它会是异步的吗?
这个问题出现的主要原因是由于上面链接的答案(here)。 @Sasxa已经(正确)回答我们可以使用同步调用从ngrx商店获取最新值:
this.http.get(restUrl)
然而,知道观察者通常是异步的,我看到了这一点,并立即想到了RACE CONDITION!在subscribe回调函数之前,该方法可能返回一个未定义的值。
我已经通过Store和Observable的内部进行了调试,这个例子确实是同步的,但我应该怎么知道呢?对于那些了解ngrx的人来说,function getState(store: Store<State>): State {
let state: State;
store.take(1).subscribe(s => state = s);
return state;
}
的{{1}}方法(用于获取最新值)是异步的,毫无疑问,因为这就是给我们反应gui的原因,这就是为什么我来到我做的假设。
这意味着我不能重构上面的代码,如下所示:
select
我可以用任何Observable来调用它,它可以用于同步生成器 - 它甚至可以用于异步生成器的某些时间,但是如果传入async observable,这毫无疑问是竞争条件。
答案 0 :(得分:5)
可以确定observable是否异步,确定是否使用异步调度程序(Scheduler.async
或Scheduler.asap
)直接进行了调度,它是否公开为foo$.scheduler
:
let schedulers = [null, Scheduler.asap];
let randomScheduler = schedulers[~~(Math.random()*2)]
let foo$ = Observable.of('foo', randomScheduler);
当进一步处理foo$
时,此信息变得更不可用,例如与其他运营商联系在一起。
并且无法确定是否会同步(在相同的刻度上)或异步生成值,因为这取决于可观察的内部:
let foo$ = new Observable(observer => {
if (~~(Math.random()*2))
setTimeout(() => observer.next('foo'));
else
observer.next('foo');
});
TL; DR:肯定无法知道。
答案 1 :(得分:3)
很难弄清楚你得到的可观察是同步还是异步(想象一下你从一个第三方库中获得了可观察的回归)。这就是为什么你以一种控制执行顺序和可预测的方式编写它的原因。
这也是为什么有像concat,combineLatest,forkjoin,switchMap,race,merge这样的运算符来帮助你获得不同场景的顺序和性能的原因