How to delay an observable without using concatMap?

Viewed 48
  public generateData(baseval, count, yrange): number[] {
    let i = 0;
    let series = [];
    while (i < count) {
      let x = Math.floor(Math.random() * (750 - 1 + 1)) + 1;
      let y =
        Math.floor(Math.random() * (yrange.max - yrange.min + 1)) + yrange.min;
      let z = Math.floor(Math.random() * (75 - 15 + 1)) + 15;

      series.push([x, y, z]);
      baseval += 86400000;
      i++;
    }
    return from(series);
  }

How to receive the result of this observable with a delay after ALL THE VALUES ARE EMITTED? Each value must not be delayed.

1 Answers

Something like:

type Range<T> = { 
  min: T
  max: T
};

type Triple<T> = [T, T, T]; 

...

public generateData(baseval: number, count: number, yrange: Range<number>): Observable<Triple<number>[]> {
  let i = 0;
  let series: Triple<number>[] = []; 
  while (i < count) {
    let x = Math.floor(Math.random() * (750 - 1 + 1)) + 1;
    let y = 
      Math.floor(Math.random() * (yrange.max - yrange.min + 1)) + yrange.min;
    let z = Math.floor(Math.random() * (75 - 15 + 1)) + 15; 

    series.push([x, y, z]);
    baseval += 86400000;
    i++;
  }

  return new Observable(observer => {
    setTimeout(() => {
      observer.next(series);
      observer.complete();
    }, 1000);
  }); 
}

where, instead of using the from function, this returns a newly created Observable that:

  • waits 1000 ms (via setTimeout), before
  • emitting one next event with the full series, and
  • emitting one complete event to finish it up

This would be called something like:

const foo = new Foo();

console.log(Date.now());
foo.generateData(100, 100, {min: 100, max: 200}).subscribe(
  next => console.log('next', Date.now(), next),
  error => console.log('error', Date.now(), error),
  () => console.log('complete', Date.now())
);

with an output something like:

1636436337853
next 1636436338868 [
  [ 616, 169, 21 ], [ 526, 126, 20 ], [ 51, 156, 54 ],  [ 174, 112, 57 ],
  [ 400, 193, 58 ], [ 195, 179, 27 ], [ 301, 179, 16 ], [ 511, 200, 38 ],
  [ 444, 181, 64 ], [ 467, 168, 29 ], [ 88, 105, 44 ],  [ 91, 184, 62 ],
  [ 664, 106, 35 ], [ 578, 153, 37 ], [ 306, 108, 60 ], [ 617, 125, 66 ],
  [ 69, 114, 57 ],  [ 629, 175, 61 ], [ 503, 156, 38 ], [ 111, 133, 21 ],
  [ 365, 195, 43 ], [ 657, 116, 50 ], [ 472, 175, 15 ], [ 744, 161, 39 ],
  [ 224, 178, 49 ], [ 243, 194, 35 ], [ 258, 144, 34 ], [ 123, 181, 52 ],
  [ 730, 191, 54 ], [ 247, 159, 27 ], [ 527, 100, 46 ], [ 539, 102, 59 ],
  [ 560, 134, 24 ], [ 135, 126, 28 ], [ 211, 162, 73 ], [ 411, 126, 56 ],
  [ 509, 199, 58 ], [ 334, 110, 35 ], [ 340, 119, 17 ], [ 6, 110, 52 ],
  [ 3, 140, 38 ],   [ 331, 104, 62 ], [ 485, 146, 37 ], [ 356, 139, 51 ],
  [ 411, 112, 30 ], [ 346, 184, 54 ], [ 248, 181, 18 ], [ 202, 186, 45 ],
  [ 278, 127, 30 ], [ 626, 147, 49 ], [ 580, 122, 40 ], [ 455, 112, 19 ],
  [ 207, 179, 56 ], [ 592, 154, 65 ], [ 303, 170, 19 ], [ 550, 126, 64 ],
  [ 495, 118, 59 ], [ 342, 164, 50 ], [ 618, 158, 42 ], [ 372, 118, 48 ],
  [ 442, 144, 71 ], [ 80, 180, 27 ],  [ 657, 158, 42 ], [ 628, 132, 33 ],
  [ 239, 183, 73 ], [ 380, 116, 18 ], [ 241, 192, 69 ], [ 207, 154, 51 ],
  [ 475, 169, 51 ], [ 129, 173, 15 ], [ 206, 170, 35 ], [ 210, 173, 37 ],
  [ 107, 170, 58 ], [ 663, 150, 60 ], [ 183, 164, 68 ], [ 183, 116, 68 ],
  [ 193, 116, 44 ], [ 167, 130, 34 ], [ 228, 105, 56 ], [ 63, 198, 28 ],
  [ 88, 196, 20 ],  [ 622, 175, 40 ], [ 488, 111, 67 ], [ 590, 156, 26 ],
  [ 553, 200, 29 ], [ 82, 137, 36 ],  [ 595, 112, 55 ], [ 95, 141, 35 ],
  [ 282, 197, 60 ], [ 53, 173, 41 ],  [ 61, 158, 41 ],  [ 29, 128, 34 ],
  [ 431, 188, 63 ], [ 182, 135, 36 ], [ 119, 142, 40 ], [ 417, 167, 21 ],
  [ 166, 133, 54 ], [ 427, 175, 63 ], [ 332, 110, 67 ], [ 572, 127, 51 ]
]
complete 1636436338873

Using delay

Alternatively, you can change the above, replacing the return with:

return from([series]).pipe(delay(1000));

which uses the delay operator to achieve the same effect.

Related