Gimy boya
Gimy boya

Reputation: 477

Repeat with a variant delay

I currently have this piece of code:

import { Observable, defer, repeat } from 'rxjs'

const randNum = () => Math.floor(Math.random() * 10) + 1

const myObs = () => {
  return defer(() => {
    let delay = randNum()
    console.log('It will be delayed by', delay, ' secounds')
    delay = delay * 1000 // convert to ms
    return new Observable((subscriber) => {
      subscriber.next('hey there')
      subscriber.complete()
    }).pipe(repeat({ delay }))
  })
}

myObs().subscribe((val) => {
  console.log('this is the val', val)
})

which will output:

It will be delayed by {insert random number from 1 to 10} secounds
this is the val hey there
this is the val hey there
this is the val hey there
.
.
.

This will go on indefinitely which is what is desired however, I want the code inside the scope of the defer function to be run every time we repeat. So what I want would output something like this:

It will be delayed by {insert random number from 1 to 10} secounds
this is the val hey there
It will be delayed by {insert random number from 1 to 10} secounds
this is the val hey there
It will be delayed by {insert random number from 1 to 10} secounds
this is the val hey there
.
.
.

So that each time I get a new random number. and I am stuck trying to achieve that with rxjs or even without it.

Note: The code I am sharing is a simplified representation of the problem I have so please don't discuss the example per se but the problem it provides. questions like why do you want a random number each time? are an example of discussing the code instead of the problem.

Upvotes: 0

Views: 91

Answers (1)

Eddy Lin
Eddy Lin

Reputation: 683

In your case like this

  • inside defer use delay delay time
  • outside defer just repeat
const randNum = () => Math.floor(Math.random() * 10) + 1

const myObs = () => {
  return defer(() => {
    let delayNum = randNum()
    console.log('It will be delayed by', delayNum, ' secounds')
    delayNum = delayNum * 1000 // convert to ms
    return new Observable((subscriber) => {
      subscriber.next('hey there')
      subscriber.complete()
    }).pipe(delay(delayNum))
  }).pipe(repeat())
}

myObs().subscribe((val) => {
  console.log('this is the val', val)
})

or use delayWhen then repeat ?

const randNum = () => Math.floor(Math.random() * 10) + 1

const source$ = new Observable((subscriber) => {
  subscriber.next('hey there')
  subscriber.complete()
});

const delayTime = () => {
  let delay = randNum()
  console.log('It will be delayed by', delay, ' secounds')
  delay = delay * 1000 // convert to ms
  return timer(delay);
}

source$.pipe(delayWhen(delayTime), repeat()).subscribe((val) => {
  console.log('this is the val', val)
})

you can also do this, just repeat, but first time won't delay.

source$.pipe(repeat({ delay: delayTime })).subscribe((val) => {
   console.log('this is the val', val)
})

Upvotes: 1

Related Questions