我在Reactive中搜索了使用延迟,但我仍然不明白为什么以及何时使用延迟方法.
据我所知,所有Observable方法在订阅之前都不会被触发,那么,为什么我们需要用defer方法包装observable方法呢?
请给我建议,如果给我举个例子,我将非常感激.
[更新]
现在我明白了.
在反应性文档中,我看到了这个例子,
var source = Rx.Observable.defer(function () {
return Rx.Observable.return(42);
});
var subscription = source.subscribe(
function (x) { console.log('Next: ' + x); },
function (err) { console.log('Error: ' + err); },
function () { console.log('Completed'); } );
Run Code Online (Sandbox Code Playgroud)
我很纳闷,
为什么它用延迟包装Observable方法?它将如何采取不同的行动?
pau*_*els 29
很简单,因为Observables可以封装许多不同类型的源,并且这些源不一定必须服从该接口.有些人Promises总是试图热切地竞争.
考虑:
var promise = $.get('https://www.google.com');
Run Code Online (Sandbox Code Playgroud)
在这种情况下的承诺已经在任何处理程序连接之前执行.如果我们希望这更像是一个行为,Observable那么我们需要某种方式推迟创建承诺,直到订阅.
因此,我们使用defer创建一个只在Observable订阅结果时才执行的块.
Observable.defer(() => $.get('https://www.google.com'));
Run Code Online (Sandbox Code Playgroud)
以上将不会创建Promise直到Observable获得订阅,因此将表现得更符合标准Observable接口.
以示例(摘自本文):
const source = Observable.defer(() => Observable.of(
Math.floor(Math.random() * 100)
));
Run Code Online (Sandbox Code Playgroud)
为什么不将sourceObservable 设置为of(Math.floor(Math.random() * 100)?
因为如果这样做,该表达式Math.floor(Math.random() * 100)将立即运行并source在我们订阅之前作为值提供source。
我们希望延迟表达式求值,所以我们包裹of在defer。现在,表达式Math.floor(Math.random() * 100)将在source订阅时(而不是任何时候)进行求值。
我们包装of(...)了defer工厂功能,以便在订阅可观察对象of(...)时进行构建source。
小智 7
如果我们考虑使用日期会更容易理解。
const s1 = of(new Date()); //will capture current date time
const s2 = defer(() => of(new Date())); //will capture date time at the moment of subscription
Run Code Online (Sandbox Code Playgroud)
对于两个 observables(s1 和 s2),我们都需要订阅。但是当 s1 被订阅时,它会在设置常量的那一刻给出日期时间。S2 将给出订阅时的日期时间。
上面的代码取自https://www.learnrxjs.io/operators/creation/defer.html