Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rxjs 如何创建一个以随机间隔产生随机数的无限可观测对象?_Rxjs - Fatal编程技术网

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)
)