Javascript 如何在RXJS中链接承诺列表?

Javascript 如何在RXJS中链接承诺列表?,javascript,asynchronous,rxjs,rxjs5,Javascript,Asynchronous,Rxjs,Rxjs5,如何在RXJS中链接承诺列表?每个承诺都需要在解决前一个问题时执行(待办工作是有状态的) 我现在这样做感觉很原始: const workTodo = []; // an array of work const allWork = Observable.create(observer => { const next= () => { const currentTodo = workTodo.shift(); if (currentTodo ) { doT

如何在RXJS中链接承诺列表?每个承诺都需要在解决前一个问题时执行(待办工作是有状态的)

我现在这样做感觉很原始:

const workTodo = []; // an array of work
const allWork = Observable.create(observer => {
  const next= () => {
    const currentTodo = workTodo.shift();
    if (currentTodo ) {
      doTodoAsync(currentTodo)
        .then(result => observer.onNext(result))
        .then(next);
    } else {
      observer.onCompleted();
    }
  };
  next();
});
我是这样想的:

const workTodo = []; // an array of work
const allWork = Observable
                  .fromArray(workTodo)
                  .flatMap(doTodoAsync);

但这基本上是一次执行所有承诺。

递归怎么样

首先创建一个递归函数并调用它
recursiveDoToDo

const recursiveDoToDo = (currentTodo, index) =>
    Observable
        .fromPromise(doTodoAsync(currentTodo))
        .map(resolved => ({resolved, index}));
上面的代码只是将您的
dotodasync
包装成一个可观察的对象,然后我们映射结果以返回数组的已解析承诺
索引,供以后递归使用

接下来,我们将使用操作符递归调用
recursiveDoToDo

recursiveDoToDo(worktodo[0], 0)
    .expand(res => recursiveDoToDo(worktodo[res.index + 1], res.index + 1))
    .take(worktodo.length)
递归只需将索引增加1。因为
.expand()
将永远递归运行,
.take()
操作符用于告诉可观察对象何时结束流,即
工作待办事项的长度

现在,您只需订阅即可:

recursion.subscribe(x => console.log(x));

这是

您的尝试似乎非常接近

您可以为
.flatMap
指定最大并发度1,如下所示:

Observable.fromArray(workTodo)
 .flatMap(doTodoAsync, 1)
或等效使用
.concatMap
而不是
.flatMap

Observable.fromArray(workTodo)
 .concatMap(doTodoAsync)
我会使用
concatMap
,因为它感觉更地道


更新:

我已经测试了
concatMap
,但它似乎做了一些稍微不同的事情。它并行执行
dotodasync
,然后按原始顺序组合结果。此处还描述了:。flatMap上的第二个参数作为编号似乎不存在。@nicojs不确定您的确切意思。用一个正在运行的演示更新了答案。它清楚地表明任务是一个接一个地执行的,并且
mergeMap/flatMap
接受
并发性
参数,如本文所述:。它似乎可以工作,但似乎也很原始。我想我更喜欢我的递归调用。我觉得应该有一个简单的操作符来做这件事。