为什么 switchMap 运算符在与 promise 一起使用时只发出最后一个值?
Why does switchMap operator only emit the last value when used with a promise?
我有点难以理解。当我将 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
这按预期工作。正如你所说的意外行为是因为 Observable.from
和 Observable.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 运算符与 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
这按预期工作。正如你所说的意外行为是因为 Observable.from
和 Observable.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