可观察的异步与同步

时间:2017-11-06 11:10:55

标签: javascript angular rxjs ngrx

我如何知道Observable制作人何时处于异步或同步状态?

同步示例:

apt-get install libffi-dev

另一个异步示例(ngrx Store,请参阅here

Observable.of([1, 2, 3])

现在是一个明显的异步示例:

this.store.take(1);

我完全理解这是如何工作的,并且一些Observable可以同步和其他异步。我不明白的是我怎么能预先区分出来?例如,生产者有一个明显的界面告诉我它会是异步的吗?

TL;博士

这个问题出现的主要原因是由于上面链接的答案(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,这毫无疑问是竞争条件。

2 个答案:

答案 0 :(得分:5)

可以确定observable是否异步,确定是否使用异步调度程序(Scheduler.asyncScheduler.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这样的运算符来帮助你获得不同场景的顺序和性能的原因