如何"每个系列"在JavaScript中使用Observables?

时间:2016-10-28 15:23:33

标签: javascript asynchronous async-await rxjs observable

我如何实现async' s eachSeries的功能,你迭代一个数组并手动调用一个回调来继续迭代?

据我所知,你可以使用RxJs迭代一个数组'可观察到this

var array = [1,2,3,4,5];

// Converts an array to an observable sequence
var source = Rx.Observable.from(array);

// Prints out each item
var subscription = source.subscribe(
  x => console.log('onNext: %s', x),
  e => console.log('onError: %s', e),
  () => console.log('onCompleted'));

// => onNext: 1
// => onNext: 2
// => onNext: 3
// => onNext: 4
// => onNext: 5
// => onCompleted

Observable自动发出"#34;每个数组元素,但我怎么能告诉它只在我需要时继续。和RxJS'一样主题next()方法。

实际上我的真实场景是我需要在观察者回调中调用其他函数。使用异步,我会传递异步回调以继续迭代到该函数并从那里调用它。但我不知道如何用Observables做到这一点。它们适合这种情况吗?或者我应该坚持异步?

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

您无法使用iterator/generator

这似乎是你想到的用例

你可以像在这个例子中那样迭代它

function *iterator(source) {
  let i = 0, len = source.length;
  for (i = 0; i < len; i++) {
    yield source[i];
  }
}

var array = [1,2,3,4,5], iter = iterator( array );

var val = iter.next();
while (!val.done) {
  console.log(`${val.value} ( done? ${val.done} )` );
  val = iter.next();
}
console.log('done');

答案 1 :(得分:0)

我认为这非常接近你所需要的:

import {Observable, Subject} from 'rxjs';

var subject = new Subject();

var interval = setInterval(_ => {
    subject.next(null);
}, 1000);

Observable.from([1,2,3,4,5])
    .concatMap(val => Observable.of(val)
        .delayWhen(_ => subject)
        .do(val => console.log('.do:', val))
    )
    .subscribe(val => console.log('next:', val), undefined, () => clearInterval(interval));

查看现场演示:http://plnkr.co/edit/v77hCqOVDBqRxpWdW4Nv?p=preview

我正在使用delayWhen()运算符来手动触发下一个值的发射。然后concatMap()等待,直到从回调中返回的前一个Observable完成,这样就可以逐个正确地调用链。

请注意,Observable.from(...)的初始排放会立即发生,每个项目都会延迟concatMap()

此演示打印到控制台:

.do: 1
next: 1
.do: 2
next: 2
.do: 3
next: 3
.do: 4
next: 4
.do: 5
next: 5