我试图教自己一些反应性函数式编程。 Ben Lesh的video显示了一个可观察的例子。我之前的阅读表明,一个可观察者是懒惰的,即它只在订阅后进行评估。奇怪的是,这段代码并不需要订阅才能打印到控制台。
var Rx = require('rxjs/Rx')
var source = Rx.Observable.from([1,2,3,4,5]);
var newSource = source.filter(x => x % 2 === 1)
.map(x => x + '!')
.forEach(x => console.log(x));
来自RxJS docs:
似乎Observable必须积极地解决.forEach发出的承诺,我对此感到困惑。
此代码引发了进一步的混淆:
var Rx = require('rxjs/Rx')
var source = Rx.Observable.from([1,2,3,4,5]);
var newSource = source.filter(x => x % 2 === 1)
.map(x => x + '!')
.do(x => console.log(x));
在运行newSource.subscribe();
之前不会评估,请帮我解释两个运营商背后的差异。
答案 0 :(得分:2)
默认情况下,Observable是懒惰的。如果你在一个observable上执行一个操作符,rxjs会为你创建一个与前一个相关联的新observable。知道可观察量是不可改变的。
然而,ForEach是一种特殊的运营商。它不会返回一个新的Observable,但它会订阅引擎盖下的observable并对该observable发出的每个元素执行一个函数。如果你检查forEach实现的源代码,它在Observable类本身上,你会看到以下内容(只是一个片段)。
const subscription = this.subscribe((value) => {
if (subscription) {
// if there is a subscription, then we can surmise
// the next handling is asynchronous. Any errors thrown
// need to be rejected explicitly and unsubscribe must be
// called manually
try {
next(value);
} catch (err) {
reject(err);
subscription.unsubscribe();
}
在这里我们可以看到observable正在订阅,价值是'next'-ed。下一个函数是传递给forEach调用的函数。