Reputation: 1
i try to get last value from a observable. the example code is
// RxJS v6+
import { lastValueFrom, Subject } from 'rxjs';
import { scan } from 'rxjs/operators';
async function main() {
const subject = new Subject();
const example = subject.pipe(
scan((acc, curr) => {
return Object.assign({}, acc, curr);
}, {}),
);
const subscribe = example.subscribe((val) =>
console.log('Accumulated object:', val),
);
subject.next({ name: 'Joe' });
subject.next({ age: 30 });
subject.next({ favoriteLanguage: 'JavaScript' });
console.log('+++++++++++++');
const resp = await lastValueFrom(example);
console.log(resp);
console.log('end');
}
main()
.catch((e) => {
console.error(e);
})
.finally(async () => {
console.log('final');
});
the output is
➜ npns-service git:(mr/master/658) ✗ ts-node prisma/test.ts
Accumulated object: { name: 'Joe' }
Accumulated object: { name: 'Joe', age: 30 }
Accumulated object: { name: 'Joe', age: 30, favoriteLanguage: 'JavaScript' }
+++++++++++++
i can't got the resp output message.
how can i got the resp value from example Observable?
Upvotes: 0
Views: 7546
Reputation: 8022
Update your code to complete your observable:
setTimeout(() => { // setTimeout is just a simple way to use JS's event loop
subject.next({ name: 'Joe' });
subject.next({ age: 30 });
subject.next({ favoriteLanguage: 'JavaScript' });
subject.complete(); // signal that our observable is done emitting
// subject.next(something) here would do
// nothing, the observable is complete
}, 0);
console.log('+++++++++++++');
const resp = await lastValueFrom(example);
console.log(resp);
console.log('end');
If you don't complete an observable, as far as your run-time is aware it may still emit something else in a minute, 5 hours, next year - who knows? There must be some condition that triggers completion.
A quick aside: I threw the code that emits on your subject into the event loop so that the code that follows can await
it. Otherwise your subject would complete synchronously before that code was ever run.
Make example
an observable that remembers (buffers) the last emission. Then just use take(1)
to read the buffered value.
const subject = new Subject();
const example = subject.pipe(
scan((acc, curr) => Object.assign({}, acc, curr), {}),
shareReplay(1)
);
example.subscribe(val =>
console.log('Accumulated object:', val)
);
subject.next({ name: 'Joe' });
subject.next({ age: 30 });
subject.next({ favoriteLanguage: 'JavaScript' });
console.log('+++++++++++++');
const resp = await lastValueFrom(example.pipe(take(1));
console.log(resp);
console.log('end');
Upvotes: 1