特定の時間までにObservableの値を生成する最も慣用的な方法は何でしょうか?たとえば、大きな配列から作成されたObservableがあり、2秒ごとに値を生成したいとします。 interval
とselectMany
の組み合わせが最善の方法ですか?
特定の例の場合、アイデアは、配列の各値を遅延後に結果を生成するオブザーバブルにマッピングし、結果のオブザーバブルのストリームを連結することです。
var delayedStream = Rx.Observable
.fromArray([1, 2, 3, 4, 5])
.map(function (value) { return Rx.Observable.return(value).delay(2000); })
.concatAll();
他の例では、実際にtimer
またはinterval
を使用する場合があります。状況次第です。
たとえば、配列が実際に非常に大きい場合、上記によりかなりのメモリプレッシャーが生じます(非常に大きいN
に対してN
オブザーバブルを作成しているため)。以下は、interval
を使用して配列を遅延ウォークする別の方法です。
var delayedStream = Rx.Observable
.interval(2000)
.take(reallyBigArray.length) // end the observable after it pulses N times
.map(function (i) { return reallyBigArray[i]; });
これは、配列全体を反復するまで、2秒ごとに配列から次の値を生成します。
Zipを使用すると、より優れた読みやすいコードが生成され、まだ3つのオブザーバブルのみを使用すると思います。
var items = ['A', 'B', 'C'];
Rx.Observable.Zip(
Rx.Observable.fromArray(items),
Rx.Observable.timer(2000, 2000),
function(item, i) { return item;}
)
ブランドンの答えはアイデアの要点を取得しますが、次のバージョンは最初のアイテムをすぐに生成し、次のアイテムの間に時間を置きます。
var delay = Rx.Observable.empty().delay(2000);
var items = Rx.Observable.fromArray([1,2,3,4,5])
.map(function (x) {
return Rx.Observable.return(x).concat(delay); // put some time after the item
})
.concatAll();
新しいRxJS用に更新:
var delay = Rx.Observable.empty().delay(2000);
var items = Rx.Observable.fromArray([1,2,3,4,5])
.concatMap(function (x) {
return Rx.Observable.of(x).concat(delay); // put some time after the item
});
RxJS 5の場合:
Rx.Observable.from([1, 2, 3, 4, 5])
.Zip(Rx.Observable.timer(0, 2000), x => x)
.subscribe(x => console.log(x));
これは言及されていなかったので、 concatMap
と組み合わせた delay
はかなり読みやすいと思います。
Rx.Observable.fromArray([1, 2, 3, 4, 5])
.concatMap(x => Rx.Observable.of(x).delay(1000));
https://codepen.io/jmendes/pen/EwaPzw を参照してください
Zipはクリーンなアプローチであることに同意します。配列の間隔ストリームを生成する再利用可能な関数は次のとおりです。
_function yieldByInterval(items, time) {
return Rx.Observable.from(items).Zip(
Rx.Observable.interval(time),
function(item, index) { return item; }
);
}
// test
yieldByInterval(['A', 'B', 'C'], 2000)
.subscribe(console.log.bind(console));
_
これは farinczの答え に基づいていますが、インスタンスメソッドとして_.Zip
_を使用することにより、少し短くなっています。
また、Rx.Observable.from()
は 非推奨 であるため、Rx.Observable.fromArray()
を使用しました。
RxJS v6の場合、2秒の遅延で次のバージョンを取得します。
例1。 concatMap:
import {of} from 'rxjs';
import {concatMap, delay} from 'rxjs/operators';
of(1, 2, 3, 4, 5)
.pipe(
concatMap(x => of(x)
.pipe(
delay(2000))
)
)
.subscribe({
next(value) {
console.log(value);
}
});
例2。マップ+ concatAll:
import {of} from 'rxjs';
import {concatAll, delay, map} from 'rxjs/operators';
of(1, 2, 3, 4, 5)
.pipe(
map(x => of(x)
.pipe(
delay(2000))
),
concatAll()
)
.subscribe({
next(value) {
console.log(value);
}
});
Farinczとuser3587412によるZipソリューションを基にした、RxJS v6での動作
const { Zip, from, timer } = require("rxjs")
const { map } = require("rxjs/operators")
const input = [1, 2, 3, 4, 5]
const delay = 2000
Zip(
from(input),
timer(0, delay)
).pipe(
map(([ delayedInput, _timer ]) => delayedInput) // throw away timer index
).subscribe(
console.log
)