javascript - Rx.Subject 丢失事件

标签 javascript rxjs rxjs5 ngrx

谁能解释一下这 3 个变体之间的区别?

http://jsfiddle.net/8vx2g3fr/2/

  1. 首先作为 expect,处理所有事件。
  2. 但是第二个输掉了最后一个事件 (3)
  3. 第三名输掉第二项比赛(2)

能否请您帮助我了解问题所在以及如何使第三个变体处理所有事件?

1

let bs = new Rx.Subject();
bs
    .subscribe(v=>{
        console.log("in", v);
        if (v % 2 == 0) {
            setTimeout(()=>{
                console.log(" out", v, "->" , v + 1);
                bs.next(v+1);
            }, 0);
        }
    });

bs.next(0);
bs.next(2);

输出:

in 0
in 2
 out 0 -> 1
in 1
 out 2 -> 3
in 3

2

let bs2 = new Rx.Subject();
bs2
    .subscribe(v=>{
        console.log("in", v);
        if (v % 2 == 0) {            
            Rx.Observable.interval(0).take(1)
                .map(()=>{console.log(" out", v, "->" , v + 1);return v+1;})
                .subscribe(bs2);
        }
    });

bs2.next(0);
bs2.next(2);

输出:

in 0
in 2
 out 0 -> 1
in 1
 out 2 -> 3

3

let bs3 = new Rx.Subject();
bs3
    .switchMap(v=>{
        console.log("in", v);
        if (v % 2 == 0) {            
            return Rx.Observable.interval(0).take(1)
                .map(()=>{console.log(" out", v, "->" , v + 1);return v+1;});
        }

    return Rx.Observable.empty();     
    }).subscribe(bs3);

bs3.next(0);
bs3.next(2);

输出:

in 0
in 2
 out 2 -> 3
in 3

最佳答案

这一切实际上都是预期的行为。

令人困惑的是,当您多次重用 Subjecttake() 等运算符时会发生什么。

运算符 take(1) 只接受一个值并发送 complete 通知。由于 .subscribe(bs2),此通知由 Subject 接收。现在是最重要的部分。
Subject 收到 completeerror 通知时,它会将自己标记为已停止。这意味着它永远不会发送任何项目或通知,这是 Rx 中正确和预期的行为。通知 completeerror 必须是最后一次发射。

因此 Subject 由第一个 take(1) 完成,它由值 0 触发(bs2.next (0) 调用)。

然后当值 2 触发 Observable.interval(0).take(1) 的第二次运行时,它被 Subject 接收但它会被自动忽略,因为 Subject 已标记为已停止。

第三个演示中的过程完全相同。

Subject.ts中的源码中可以看到:

关于javascript - Rx.Subject 丢失事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41786396/

相关文章:

javascript - 在本地主机上开发时 Jquery.min.js 403 Forbidden

angular - RxJS 如何按顺序发出 POST 请求,只有在前一个请求完成后才会触发新请求?

angular - 如何创建在验证后返回 Observable 的函数?

redux - 测试 redux-observable 史诗的错误处理

javascript - Observable 最后订阅

javascript - EventListener 会立即触发,除非封装在匿名函数中,然后阻止 RemoveEventListener

javascript - 使用combineReducers "Error: Reducer "assetReducer时出错“初始化期间返回未定义”。

javascript - 在 RxJS 中排序数组

angular - 结合多个最新版本的 observable、ngrx

javascript - 在子组件的 ngAfterViewInit() 中调用时,父组件的元素上的 getElementById 返回 null