我有一个处理来自列表的请求的异步函数,但是当每个请求完成时,它没有像声明之前那样排序(因为它是异步的)。如何异步获取但保留原始顺序?
这里是小提琴http://jsbin.com/papunixume/edit?html,js,console
// clear console every single run
console.clear()
// create promise
const cp = (msg, timeout) => {
return new Promise(resolve => {
setTimeout(() => {
resolve(msg)
}, timeout)
})
}
const a = cp('a', 1000)
const b = cp('b', 500)
const c = cp('c', 800)
Rx.Observable.of([a, b, c]).subscribe(val => {
val.map(res => {
res.then(x => console.log(x))
})
})
结果是
"b"
"c"
"a"
预期
"a"
"b"
"c"
答案 0 :(得分:3)
这实际上取决于您需要使用Promises的方式和方式。你现在所拥有的东西根本不需要RxJS,因为你只是创建一个Promises数组,然后在每个上面调用then()
。
如果你想做更多" RxJS方式"您可以在Promise到达时收集结果,同时使用concatMap()
运算符保持相同的顺序:
Rx.Observable.from([a, b, c])
.concatMap(promise => promise)
.subscribe(val => console.log(val));
魔法发生在concatMap()
内部,因为它识别Promise类的一个实例并以特殊方式处理它们(用then()
链接它们并重新发送它们的结果)。
请参阅演示:http://jsbin.com/gobayoy/4/edit?js,console
或者您可以等到所有Promise完成,然后将所有结果作为单个数组发出forkJoin()
:
Rx.Observable.forkJoin(a, b, c)
.subscribe(val => console.log(val));
请参阅演示:http://jsbin.com/zojuya/2/edit?js,console
同样,RxJS自动处理Promises,因此forkJoin()
能够等待所有Promise完成,而不必担心它。