给定一个生成随机数的函数,你会如何创建一个随机间隔产生随机数的无限Observable?
function getRandomNumber() {
// Assume this function returns a random number, e.g. 198
}
function getRandomDelay() {
// Assume this function returns a random delay in ms, e.g. 2000
}
以下是所需Observable的示例:
---198--------64-------3---2----------18-------> (indefinitely)
3ms 7ms 6ms 3ms 10ms
答案 0 :(得分:9)
作为替代方案,如果您不想生活在令人困惑的超时世界中,您可以完全将其写为流:
// the stream
const randomizer$ = Rx.Observable.of("")
.switchMap(() => Rx.Observable
.timer(getRandomDelay())
.mapTo(getRandomNumber()))
.repeat();
// subscribe to it
randomizer$.subscribe(num => console.log("Random number after random delay" + num));
// your utility functions
function getRandomNumber() {
return ~~(Math.random() * 200)
}
function getRandomDelay() {
return Math.random() * 1000
}
这里的工作示例:http://jsbin.com/zipocaneya/edit?js,console
备选方案:首先创建随机数,然后添加延迟(如果执行时间无关紧要)
// the stream
const randomizer$ = Rx.Observable.of("")
.switchMap(() => Rx.Observable
.of(getRandomNumber())
.delay(getRandomDelay()
)
.repeat();
// subscribe to it
randomizer$.subscribe(num => console.log("Random number after random delay" + num));
附加说明:由于流外部没有并发或异步操作,而不是switchMap
,您也可以使用concatMap
或{{ 1}} - 在这种情况下,它们都是一样的。
答案 1 :(得分:7)
const { Observable } = require("rxjs");
const ob = new Observable(sub => {
let timeout = null;
// recursively send a random number to the subscriber
// after a random delay
(function push() {
timeout = setTimeout(
() => {
sub.next(getRandomNumber());
push();
},
getRandomDelay()
);
})();
// clear any pending timeout on teardown
return () => clearTimeout(timeout);
});
ob.subscribe(console.log);
答案 2 :(得分:0)
您能看看https://github.com/cszredwan/crazyObservable吗? 我敢肯定这会有所帮助,这是一个可观察到的习惯,可以在固定的时间范围内发出(随机!)固定数量的数据。
您的问题是随机使用的含义不精确。 crazyObservable绘制单个数据流,其中包含在指定时间范围内发出数据的所有可能性。当然,您可以合并crazyObservable的多个实例以获得所需的行为。
答案 3 :(得分:0)
在RxPY 3.0中,您可以使用以下结构:
res = rx.generate(0, lambda x: True, lambda x: x + 1).pipe(
ops.map(lambda x: rx.timer(random.random() * 0.4).pipe(ops.map(lambda y: x))),
ops.merge(max_concurrent=1),
ops.map(lambda x: {'count': x, 'value': random.randint(0, 5)}))
这会在随机时间生成一个介于0到5之间的无限整数的无限流,到达间隔时间均匀地分布在[0,0.4]上。
在RxPY 3.0中,未实现switchmap或concatmap之类的操作(如@olsn的回复)。通过与max_concurrent = 1合并可以实现concat_all操作。
编辑:
rx.generate(0, lambda x: True, lambda x: x + 1)
正在阻止。使用无限的香草python生成器,例如
import itertools
r = rx.from_iterable(_ for _ in itertools.count(start=0, step=1))
也在阻止。您可以添加一些计划程序,例如
from rx.scheduler.eventloop import AsyncIOScheduler
from rx.scheduler import ThreadPoolScheduler
import multiprocessing
scheduler = AsyncIOScheduler(asyncio.get_event_loop())
# scheduler = ThreadPoolScheduler(multiprocessing.cpu_count()) # alternatively
res = rx.generate(0, lambda x: True, lambda x: x + 1).pipe(
ops.map(lambda x: rx.timer(random.random() * 0.4).pipe(ops.map(lambda y: x))),
ops.merge(max_concurrent=1),
ops.map(lambda x: {'count': x, 'value': random.randint(0, 5)}),
ops.subscribe_on(scheduler)
)