0
votes

I have an Observable myObservable which gets some items emitted with different time intervals. For example the time interval between the first and the second item could be 1 second and for the second and third item this could be 3 seconds. For each item a HTTP request is send with the method this.sendMessage().

The problem is that the time interval between the request should be at least two second. Delay all request for two seconds is not the best solution. For example for the first request I don't want a delay. I don't want a delay too when the time difference between two emitted items is more than two seconds.

This is a working solution which does what I want. But I wonder if there is a more rxjs-like solution? I play with delay() and delayWhen() but I didn't find a way to get this working. Does anyone has a solution?

let lastSendTimestamp = null;

myObservable.pipe(
  concatMap(async body => {

    // Calculate delay time
    let delayTime = 0;
    if (!lastSendTimestamp) {
      delayTime = 0;
    } else if (Date.now() - lastSendTimestamp > 2000) {
      delayTime = 0;
    } else {
      delayTime = 2000 - (Date.now() - lastSendTimestamp);
    }

    // Wait until delay is over
    await new Promise(resolve => setTimeout(resolve, delayTime));

    lastSendTimestamp = Date.now();

    return await this.sendMessage(body);
  }),
).subscribe(result => {
});
1

1 Answers

0
votes

You can use timer instead and chain with the async request. There's no need for promise

let lastSendTimestamp = null;

myObservable.pipe(
  concatMap(body => {

    // Calculate delay time
    let delayTime = 0;
    if (!lastSendTimestamp) {
      delayTime = 0;
    } else if (Date.now() - lastSendTimestamp > 2000) {
      delayTime = 0;
    } else {
      delayTime = 2000 - (Date.now() - lastSendTimestamp);
    }
    lastSendTimestamp = Date.now();
    return timer(delayTime).pipe(concatMap(res=>this.sendMessage(body)));
  }),
).