Javascript 如何在RXJS中链接承诺列表?
如何在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
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
接受并发性
参数,如本文所述:。它似乎可以工作,但似乎也很原始。我想我更喜欢我的递归调用。我觉得应该有一个简单的操作符来做这件事。