在列表上异步操作时保留结果的顺序 [英] Preserve order of results when operating asynchronously on a list

查看:98
本文介绍了在列表上异步操作时保留结果的顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个异步函数来处理列表中的请求,但是当每个请求完成后,它的顺序就不会像声明之前那样(因为它是异步的).如何异步获取但保留原始顺序?

I have an asynchronous function that processes requests from a list, but when each request is done, it's not ordered like before declared (since it's async). How can I fetch asynchronously but retain the original ordering?

这是小提琴 http://jsbin.com/papunixume/edit?html,js,控制台

// 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"

推荐答案

这实际上取决于您与Promises合作的方式和方式.您现在拥有的资源根本不需要RxJS,因为您只需要创建一个Promises数组,然后在每个Promises上调用 then().

This really depends on what and how you need to work with the Promises. What you have now doesn't need RxJS at all because you're just creating an array of Promises and then calling then() on each of them.

如果您想以更多的"RxJS方式"进行操作,则可以在Promises到达时收集结果,同时使用 concatMap()运算符保持相同的顺序:

If you want to do in more "RxJS way" you can collect results from the Promises as they arrive while maintaining the same order with the concatMap() operator:

Rx.Observable.from([a, b, c])
  .concatMap(promise => promise)
  .subscribe(val => console.log(val));

魔术发生在 concatMap()内部,因为它可以识别Promise类的实例并以特殊方式处理它们(将它们与 then()链接并重新发出它们)结果).

The magic happens inside concatMap() because it recognizes an instance of a Promise class and handles them in a special way (chains them with then() and reemits theirs result).

请参阅演示: http://jsbin.com/gobayoy/4/edit?js控制台

或者您可以等到所有Promise都完成后,再使用 forkJoin()将它们的所有结果作为单个数组发出:

Or you can wait until all of the Promises complete and then emit all their results as a single array with forkJoin():

Rx.Observable.forkJoin(a, b, c)
  .subscribe(val => console.log(val));

请参阅演示: http://jsbin.com/zojuya/2/edit?js控制台

同样,RxJS自动处理Promise,因此 forkJoin()可以等待所有Promise完成,而无需担心.

Again, RxJS handles Promises automatically so forkJoin() is able to wait for all Promises to finish without you worrying about it.

这篇关于在列表上异步操作时保留结果的顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆