Javascript RxJs-what';s observer.isStopped、observer.observer.isStopped和observed.m.isDisposed之间的差异

Javascript RxJs-what';s observer.isStopped、observer.observer.isStopped和observed.m.isDisposed之间的差异,javascript,rxjs,Javascript,Rxjs,我想找到一种方法来检测观察者是否已经完成使用定制的observable,这是我用Rx.obbservable.create创建的,这样定制的observable就可以结束它并正确地进行一些清理 因此,我创建了一些测试代码,如下所示,以确定观测者对象上可用于此目的的字段类型 var Rx = require("rx") var source = Rx.Observable.create(function (observer) { var i = 0; setInterval(funct

我想找到一种方法来检测观察者是否已经完成使用定制的observable,这是我用Rx.obbservable.create创建的,这样定制的observable就可以结束它并正确地进行一些清理

因此,我创建了一些测试代码,如下所示,以确定观测者对象上可用于此目的的字段类型

var Rx = require("rx")

var source = Rx.Observable.create(function (observer) {

  var i = 0;
  setInterval(function(){
    observer.onNext(i);
    console.dir(observer);
    i+=1
  }, 1000)

});

var subscription = source.take(2).subscribe(
  function (x) { console.log('onNext: %s', x); }
);
输出如下

onNext: 0
{ isStopped: false,
  observer: 
   { isStopped: false,
     _onNext: [Function],
     _onError: [Function],
     _onCompleted: [Function] },
  m: { isDisposed: false, current: { dispose: [Function] } } }
onNext: 1
onCompleted
{ isStopped: true,
  observer: 
   { isStopped: false,
     _onNext: [Function],
     _onError: [Function],
     _onCompleted: [Function] },
  m: { isDisposed: true, current: null } }
观察者对象上似乎有3个字段与我的目标有关,即observer.isStopped、observer.observer.isStopped和observer.m.istiposed

我想知道它们都是关于什么的,我应该选择哪一个

============================================================================== 我的问题的动机

根据Andre的建议,我添加了引发我问题的场景

在我的应用程序中,我试图基于window.requestAnimationFrame(回调)机制制作一些UI动画。requestAnimationFrame将在浏览器渲染引擎确定的时间内调用提供的回调。回调应该执行一些动画步骤,并递归地再次调用requestAnimationFrame,直到动画结束

我想把这个机制抽象成一个可观察的模型,如下所示

function animationFrameRenderingEventsObservable(){
    return Rx.Observable.create(function(subscriber){
        var fn = function(frameTimestmpInMs){
            subscriber.onNext(frameTimestmpInMs);
            window.requestAnimationFrame(fn)
        };
        window.requestAnimationFrameb(fn);
    });
}
然后我可以在需要动画的不同地方使用它。例如,我需要绘制一些动画,直到用户触摸屏幕,我才开始

 animationFrameRenderingEventsObservable()
   .takeUntil(touchStartEventObservable)
   .subscribe( animationFunc )
但是,我需要一种方法在takeUntil(touchStartEventObservable)结束订阅后停止AnimationFrameRenderingEventsAbservable中的无限递归

因此,我修改了AnimationFrameRenderingEventsBServable以

function animationFrameRenderingEventsObservable(){
    return Rx.Observable.create(function(subscriber){
        var fn = function(frameTimestmpInMs){
            if (!subscriber.isStopped){
                subscriber.onNext(frameTimestmpInMs);
                window.requestAnimationFrame(fn)
            }else{
                subscriber.onCompleted();
            }
        };
        window.requestAnimationFrameb(fn);
    });
}

根据我的测试,代码按预期工作。但是,如Andre所述,如果使用subscriber.isStopped或类似的方法不正确,那么正确的方法是什么?

如果您使用observer.isStopped或相关的方法,则表明您做错了什么。这些不是API函数,而是实现细节

我想找到一种方法来检测观察者是否已经完成使用定制的observable,这是我用Rx.obbservable.create创建的,这样定制的observable就可以结束它并正确地进行一些清理

当“未完成”发生时,观察者会进行清理。在上面的Seababy.Read中,当你考虑自定义可观察到的结束时,你应该调用<代码>观察者.OnEndoDead()/Cyto>,或者永远不要调用<代码>观察者.OnEnguldEd()/>代码>如果自定义可观察的意思是无限的。另外,您应该将整个代码包装在Observable.create中,并在catch中使用try/catch调用
observator.onError(err)

如果您试图在观察者“使用完可观察对象”时对其进行“清理”,那么您就做错了。本质上,如果定制的可观察者需要对观察者做出反应,那么这意味着观察者也应该是可观察者。很可能,Observable.create不是用于此目的的工具

最好说出你想要完成什么,而不是如何做一些具体的事情

更新:


基于您想要执行的动画:在RxJS的上下文中,requestAnimationFrame是一个调度器,而不是一个可观察的

在您提供给
create
的函数中,您可以返回一个cleanup函数,以便在观察者取消订阅您的被观察者时调用。您应该提供一个停止动画帧请求的函数。这是我几年前写的一个工作的可观察对象,它可以满足你的需求:

Rx.Observable.animationFrames = function () {
    /// <summary>
    /// Returns an observable that triggers on every animation frame (see https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame ).
    /// The value that comes through the observable is the time(ms) since the previous frame (or the time since the subscribe call for the first frame)
    /// </summary>
    var request = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame,
        cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame ||
            window.msCancelAnimationFrame || window.msCancelRequestAnimationFrame;

    return Rx.Observable.create(function (observer) {
        var requestId,
            startTime = window.mozAnimationStartTime || Date.now(),
            callback = function (currentTime) {
                // If we have not been disposed, then request the next frame
                if (requestId !== undefined) {
                    requestId = request(callback);
                }

                observer.onNext(Math.max(0, currentTime - startTime));
                startTime = currentTime;
            };

        requestId = request(callback);

        return function () {
            if (requestId !== undefined) {
                var r = requestId;
                requestId = undefined;
                cancel(r);
            }
        };
    });
};

Andre,我更新了我的问题,加入了可以解释我动机的情景。基本上,如果定制观察者需要对观察者做出反应,然后,这意味着观察者也应该是可观察的非真实Rx为2个特定事件建立了从观察者到可观察者的通信通道:观察者订阅时通知可观察者,观察者取消订阅时通知观察者。正是这种机制允许冷观测和热观测,更根本的是,如果没有人观看,懒惰观测不会消耗资源。虽然Andre使用requestAnimationFrame调度器的解决方案是我最初场景的完美答案,但Brandon的解决方案更符合我在这个问题中提出的要求。所以我选择了他的一个。是的,我也喜欢他的解决方案。
requestAnimationFrame
调度程序不能用于对某些事件进行采样并删除其他事件,不是吗?(比如鼠标事件,否则会影响性能。)我想我们仍然需要一个可观察的,结合
.sample
Rx.Observable.animationFrames().take(5).subscribe(function (msSinceLastFrame) { ... });