【问题标题】:Why does switchMap operator only emit the last value when used with a promise?为什么 switchMap 运算符在与 promise 一起使用时只发出最后一个值?
【发布时间】:2018-07-28 08:19:48
【问题描述】:

我很难理解这一点。当我将 switchMap 运算符与 Observable 一起使用时,它会按预期发出所有值:

Observable.from([1, 2, 3, 4, 5])
    .do(console.log)
    .switchMap(i => Observable.of('*' + i))
    .do(console.log)
    .subscribe();

结果:

1
*1
2
*2
3
*3
4
*4
5
*5

但是当我用 Promise 替换 Observable 时,我得到了不同的行为:

Observable.from([1, 2, 3, 4, 5])
    .do(console.log)
    .switchMap(i => new Promise((resolve) => resolve('*' + i)))
    .do(console.log)
    .subscribe();

结果:

1
2
3
4
5
*5

【问题讨论】:

    标签: promise rxjs observable rxjs5 switchmap


    【解决方案1】:

    这按预期工作。您所说的意外行为是因为Observable.fromObservable.of 始终严格同步,而new Promise 不一定不同步(我不确定规范,所以也许这就是Promise 在所有浏览器中必须做的)。

    无论如何,您都可以通过传递 async 调度程序来强制 Observable.from 异步发射。

    import { Observable } from 'rxjs';
    import { async } from 'rxjs/scheduler/async';
    
    Observable.from([1, 2, 3, 4, 5], async)
        .do(console.log)
        .switchMap(i => new Promise((resolve) => resolve('*' + i)))
        .do(console.log)
        .subscribe();
    

    现在每个发射都在一个新的帧中,就像Promise 一样,输出与您预期的一样。

    查看现场演示(打开控制台):https://stackblitz.com/edit/rxjs5-gfeqsn?file=index.ts

    【讨论】:

    • 这完全有道理!但是你能解释一下为什么在单独的帧中发射的事实会这样吗?我希望将所有排放量作为输出。 (或者我可能不理解 switchMap 的预期行为。)谢谢。 @马丁
    • 那是因为switchMap 接收1 并订阅new Promise()。然后在同一帧中,它接收2 并取消订阅以前的Promise 并订阅新的,依此类推。只有在5 及其Promise 之后,框架才结束,JS 评估另一个框架,其中只有最后一个活动的Promise 被解析。
    猜你喜欢
    • 2021-12-17
    • 2016-06-07
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 2019-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多