Rxjs,理解推迟

Exp*_* be 15 rxjs

我在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接口.

  • 我认为他的意思是,如果你执行 `fromPromise(promise)`,则传递给 `fromPromise` 的 `promise` 已经在执行,而 `fromPromise` 只是在 Observable 包装器中返回该承诺。通过使用`defer`,在我们订阅之前承诺不会开始执行。 (3认同)

Ole*_*Ole 7

以示例(摘自本文):

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

我们希望延迟表达式求值,所以我们包裹ofdefer。现在,表达式Math.floor(Math.random() * 100)将在source订阅时(而不是任何时候)进行求值。

我们包装of(...)defer工厂功能,以便在订阅可观察对象of(...)时进行构建source

  • 还需要指出的是,`defer()`返回的Observable会在每次被预订时运行提供的工厂函数。因此,仅使用`of(Math.floor(Math.random()* 100))`时,每个订阅者都会收到相同的随机数,该随机数是预先计算的。将其包装在`defer()`中时,每个订阅者将收到一个不同的随机数,该随机数是在订阅时计算的。 (5认同)

小智 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