Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create an infinite Observable that produces random numbers at random intervals?

Tags:

rxjs

Given a function that generates random numbers, how would you create an infinite Observable that produces random numbers at random intervals?

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
}

Here is an example of a desired Observable:

---198--------64-------3---2----------18------->  (indefinitely)

3ms     7ms       6ms   3ms     10ms
like image 348
Misha Moroshko Avatar asked Dec 29 '16 22:12

Misha Moroshko


People also ask

What is random number interval?

A random number occurs in a specified distribution only when two conditions are met: The values are uniformly distributed over a defined interval or set, and it is impossible to predict future values based on past or present ones.

What random number generator does MATLAB use?

(Pseudo)Random numbers in MATLAB® come from the rand , randi , and randn functions. Many other functions call those three, but those are the fundamental building blocks. All three depend on a single shared random number generator that you can control using rng .

How to fix random numbers in MATLAB?

Set and Restore Generator SettingsSet the random number generator to the default seed ( 0 ) and algorithm (Mersenne Twister), then save the generator settings. Create a 1-by-5 row vector of random values between 0 and 1. Change the generator seed and algorithm, and create a new random row vector.


2 Answers

As an alternative, if you don't want to live in a confusing timeout-world, you could write this entirely as a stream:

// 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
}

Working example here: http://jsbin.com/zipocaneya/edit?js,console


Alternative: Create the random number first and then add a delay (if the time of execution does not matter)

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

Additional note: Since there is no concurrency or async-operation going on outside of the stream, instead of switchMap you could just as well use concatMap or flatMap - in this case they all work the same.

like image 198
olsn Avatar answered Oct 26 '22 01:10

olsn


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);
like image 40
nickclaw Avatar answered Oct 26 '22 00:10

nickclaw



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!