Rxjs 如何创建一个以随机间隔产生随机数的无限可观测对象?
给定一个生成随机数的函数,您如何创建一个以随机间隔生成随机数的无限可观测值Rxjs 如何创建一个以随机间隔产生随机数的无限可观测对象?,rxjs,Rxjs,给定一个生成随机数的函数,您如何创建一个以随机间隔生成随机数的无限可观测值 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 } 以下是一个期望可观测的示例: ---198--
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
}
以下是一个期望可观测的示例:
---198--------64-------3---2----------18-------> (indefinitely)
3ms 7ms 6ms 3ms 10ms
另一种选择是,如果您不想生活在一个混乱的超时世界中,您可以将其完全写成流:
// 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
}
此处的工作示例:
备选方案:首先创建随机数,然后添加延迟(如果执行时间无关紧要)
附加说明:由于流之外没有并发或异步操作,因此您可以使用
concatMap
或flatMap
,而不是switchMap
,在这种情况下,它们的工作原理相同。您能看一下吗?
我相信这会有所帮助,这是一个定制的可观察到的在固定时间范围内(随机!)发射固定数量的数据
你问题的问题是随机性被用来表达不精确的意思。crazyObservable在指定的时间范围内绘制所有可能发出数据的单一数据流。当然,您可以将crazyObservable的多个实例合并以获得所需的行为。在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的回复)。concat_all操作可以通过合并max_concurrent=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)
)
谢谢我试图使用像
concatMap()
这样的方法,但您的方法看起来更简单。谢谢!这看起来有点简单:Rx.Observable.of('').concatMap(()=>Rx.Observable.of(getRandomNumber()).delay(getRandomDelay()).repeat()
但它不同-如果您的随机数创建取决于一些现有的,可变数据那么,在执行实际逻辑时,它确实很重要:在延迟之前或之后,更常见的情况是在延迟之后执行-但我稍后将编辑答案并将其添加为选项不确定我是否理解。在“替代”解决方案中,数字是在延迟之后而不是之前发出的。发射的时间是相同的,是的-但是生成随机数的时间是不同的-不确定这是否对你的情况有影响,但我有其他的情况,其中,delay
是在复杂的计算之后添加的,到发出时,计算值已经过时-在这种情况下,最好先延迟,然后再进行计算(对您来说,这很可能不会有什么不同,尤其是当您仅使用Math.random()
时)这里不需要repeat(),它已经是一个无限流了。
rx.generate(0, lambda x: True, lambda x: x + 1)
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)
)