简体   繁体   English

RxJS Observable立即返回数据,为什么?

[英]RxJS Observable returns data immediately, why?

In my current project I've found the function given below: 在我目前的项目中,我发现了下面给出的函数:

translateString(stringToTranslate: string) {
    let translation;
    this.translateService.get(stringToTranslate).subscribe(
        data => {
            translation = data;
        });
    return translation;
}

It looks ridiculous since TranslateService.get() method returns an Observable in every case, but it actually works somehow (the translated string is returned immediately)... What is the explanation of this behavior? 它看起来很荒谬,因为TranslateService.get()方法在每种情况下都返回一个Observable,但它实际上以某种方式工作(翻译的字符串立即返回)...这种行为的解释是什么? Shouldn't callback function be added to the execution stack and run later? 不应该将回调函数添加到执行堆栈并稍后运行吗?

The fact you're using Observables doesn't automatically mean that everything is going to be called in a separate JavaScript callback. 您使用Observables这一事实并不意味着将在单独的JavaScript回调中调用所有内容。

In fact most of the default Observables and operators emit everything immediately and don't use any Scheduler by default. 实际上,大多数默认的Observable和运算符都会立即发出所有内容,默认情况下不使用任何Scheduler。 For example have a look at this https://github.com/ReactiveX/rxjs/blob/master/src/observable/ArrayObservable.ts#L118 例如,看看这个https://github.com/ReactiveX/rxjs/blob/master/src/observable/ArrayObservable.ts#L118

This is obviously different when using for example the delay() operator which needs to schedule execution, see https://github.com/ReactiveX/rxjs/blob/master/src/operator/delay.ts#L52 . 当使用例如需要安排执行的delay()运算符时,这显然是不同的,请参阅https://github.com/ReactiveX/rxjs/blob/master/src/operator/delay.ts#L52

For example consider the following example: 例如,请考虑以下示例:

Observable.from([1,2,3], Scheduler.async)
  .subscribe(val => console.log(val));

Observable.from(['a','b','c'], Scheduler.async)
  .subscribe(val => console.log(val));

Which schedules each emission into another JS callback: 将每个发射计划到另一个JS回调中:

1
"a"
2
"b"
3
"c"

See demo: https://jsbin.com/zalugev/3/edit?js,console 请参阅演示: https//jsbin.com/zalugev/3/edit?js,console

If you don't set any scheduler everything will be emitted immediately (synchronously): 如果您没有设置任何调度程序,将立即(同步)发出所有内容:

Observable.from([1,2,3])
  .subscribe(val => console.log(val));

Observable.from(['a','b','c'])
  .subscribe(val => console.log(val));

Which prints the following: 其中打印以下内容:

1
2
3
"a"
"b"
"c"

See demo: https://jsbin.com/zalugev/4/edit?js,console 请参阅演示: https//jsbin.com/zalugev/4/edit?js,console

Regarding your question, you shouldn't rely on the 3rd party library to emit values immediately because you never know when this changes and your code will break. 关于你的问题,你不应该依赖第三方库立即发出值,因为你永远不知道什么时候这个改变而你的代码会破坏。

Not sure if that could be the issue here, but some observables emit synchronously. 不确定这可能是问题,但是一些可观察量同步发出。 This is the case of Observable.of for example I believe. 这是Observable.of的情况,例如我相信。 If translateService is synchronous, you would then immediately get your subscription observer called and your translation value filled. 如果translateService是同步的,那么您将立即调用您的订阅观察者并填充您的translation值。

You can influence the timing of the emission by using schedulers, which is probably the less documented part of rxjs. 您可以使用调度程序来影响发射的时间,这可能是rxjs记录较少的部分。 Have a look at https://github.com/ReactiveX/rxjs/blob/master/MIGRATION.md , section Schedulers Renamed 请查看https://github.com/ReactiveX/rxjs/blob/master/MIGRATION.mdSchedulers Renamed部分

An Observable is essentially just a wrapper for onSuccess() , onError() and onComplete() callbacks. Observable本质上只是onSuccess()onError()onComplete()回调的包装器。 If functions that are executed are synchronous an Observable will be too. 如果执行的函数是同步的,则Observable也是同步的。 This is core functionality of an Observable (the rest is just cleanup): 这是Observable的核心功能(其余的只是清理):

export class Observable {
  constructor(subscribe) {}
  subscribe(observerOrNext, error, complete) {} // callbacks
}
Observable.create = (subscribe) => {
    return new Observable(subscribe); // dot-chaining
}

Watch this video where André Staltz constructs observable from scratch. 观看此视频 ,AndréStaltz从头开始构建可观察的视频

Your translateString function returns immediately because of your return translation line fires before the observable completes. 您的translateString函数会立即返回,因为在observable完成之前您的return translation行会触发。 Observables are async and thus your this.translateService.get(stringToTranslate) hasn't completed before the return statement. Observable是异步的,因此你的this.translateService.get(stringToTranslate)return语句之前还没有完成。

I would remove the return statement and just let the data value get assigned to translation when the observable completes. 我将删除return语句,并在observable完成时让数据值分配给translation If you are trying to chain functions together, I would look at flatMap to call another function on the response of this.translateService.get(stringToTranslate) . 如果您尝试将函数链接在一起,我会查看flatMap以调用this.translateService.get(stringToTranslate)的响应上的另一个函数。

The subscribe behaves in a way like a callback in that it executes the observable and gives the response in a success/error/completed fashion. subscribe行为类似于回调,因为它执行observable并以成功/错误/完成的方式提供响应。

....subscribe(
    data => //success data,
    error => //error data,
    completed => //observable completed
);

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

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