如何从Observable获取最后一个值?解决lastValueFrom无返回问题
问题描述
我尝试从Observable中获取最后一个值,所用示例代码如下:
// 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'); });
运行代码后得到的输出如下:
➜ 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' } +++++++++++++
执行过程中始终无法得到resp的输出内容,请问如何才能正确从example这个Observable中获取到对应的响应值?
问题原因
lastValueFrom 会等待目标Observable进入完成(complete)状态,才会resolve返回Observable此前发出的最后一个值。
代码中只调用了subject.next()推送值,从未触发流的完成通知,Observable始终处于存活等待新值的状态,await lastValueFrom(example)会一直挂起,自然不会执行后续打印resp的逻辑。
修复方案
在所有值推送完成后,调用subject.complete()结束流即可,修改后的核心代码段如下:
// 前面逻辑保持不变 subject.next({ name: 'Joe' }); subject.next({ age: 30 }); subject.next({ favoriteLanguage: 'JavaScript' }); // 新增:通知Subject所有值发送完毕,流结束 subject.complete(); console.log('+++++++++++++'); const resp = await lastValueFrom(example); console.log(resp); console.log('end'); // 后面逻辑保持不变
修改后运行就能正常拿到累积后的最终对象,正常输出end和final日志。
注意:如果你的Subject后续还需要推送新值,不能直接调用complete结束流,这种场景要取当前最新值不要用lastValueFrom,应该用BehaviorSubject/ReplaySubject存储最新值,按需读取即可。
内容的提问来源于stack exchange,提问作者kula
相关产品推荐
相关产品推荐

