I wanted to test if delayWhen needs a value-emission to work or if a complete-signal from the passed observable is also enough.
To test this, I wrote this piece of code:
import { of, EMPTY } from 'rxjs';
import { delayWhen, delay } from 'rxjs/operators';
const a$ = of('Hello');
const delay$ = EMPTY.pipe(delay(2000));
const new$ = a$.pipe(delayWhen(() => delay$));
new$.subscribe({
next: (value) => console.log('Value:', value),
complete: () => console.log('Complete'),
error: (err) => console.error('Error:', err),
});
I expected to get a console log that logs ‘Hello’ and then a ‘Complete’-Message, but this did not happen.
Instead I see only a complete-Message.
Check out the result here.
Two questions:
- Is delayWhen also working if the inner observable just completes?
- Why is my way to ‘test’ this above not working as expected?
EMPTY
only emits the complete notification as per docs, so the stream immediately complete hence you are getting only complete
logged. So completed EMPTY
does not wait for delay(2000ms) to happen.
Instead use of(true)
followed by delay
, of
will emit and then complete, in this scenario, the delay works fine, since its an emit, followed by a complete. So it will log Value: Hello; complete
.
So a complete notification does not care what the downstream operations do, it just completes ASAP.
import { of, EMPTY } from 'rxjs';
import { delayWhen, delay } from 'rxjs/operators';
// Quell-Observable, das sofort einen Wert emittiert und dann abschließt
const a$ = of('Hello');
// Inneres Observable, das nach 2 Sekunden einfach nur abschließt
const delay$ = of(true).pipe(delay(2000));
// Neues Observable mit delayWhen
const new$ = a$.pipe(delayWhen(() => delay$));
// Subscribe to the new observable to see the behavior
new$.subscribe({
next: (value) => console.log('Value:', value),
complete: () => console.log('Complete'),
error: (err) => console.error('Error:', err),
});
Stackblitz Demo