如何等待Observable执行完毕后再同步执行后续代码?
核心前提说明
JavaScript 执行严格遵循事件循环机制:同步栈内的所有代码会先执行完毕,才会处理异步队列的回调任务(包括 Observable 内部的 setTimeout 回调、RxJS 流的通知回调)。如果你要求console.log('ready')完全保持现有同步位置、不做任何上下文调整,不可能实现等待异步 Observable 执行完成再触发的需求。
可行落地方案
现有标准下最贴合你需求的方案是使用顶层 await(ES2022+ 规范支持,Node.js 14.8+、现代浏览器均原生支持),无需将打印逻辑移入 subscribe 回调,仅需将 Observable 转为 Promise 等待执行完成即可:
import { Observable, concatMap, lastValueFrom } from 'rxjs'; let o1 = Observable.create((o) => { console.log('o1 start'); setTimeout(() => { console.log(`o1 is running`); o.next('o1'); o.complete(); // 必须触发complete通知流终止,否则无法判断执行结束 }, 1500); console.log('o1 ends'); }); let o2 = Observable.create((o) => { console.log('o2 starts'); setTimeout(() => { console.log(`o2 is running`); o.next('o2'); o.complete(); // 必须触发complete通知流终止 }, 1100); console.log('o2 ends'); }); // 等待流执行完成再往下走 await lastValueFrom(o1.pipe(concatMap(() => o2))); console.log(`ready`);
如果你的运行环境不支持顶层 await,可以用自执行 async 函数做外层包裹,打印逻辑依然可以保持原有相对顺序:
import { Observable, concatMap, lastValueFrom } from 'rxjs'; (async () => { let o1 = Observable.create((o) => { console.log('o1 start'); setTimeout(() => { console.log(`o1 is running`); o.next('o1'); o.complete(); }, 1500); console.log('o1 ends'); }); let o2 = Observable.create((o) => { console.log('o2 starts'); setTimeout(() => { console.log(`o2 is running`); o.next('o2'); o.complete(); }, 1100); console.log('o2 ends'); }); await lastValueFrom(o1.pipe(concatMap(() => o2))); console.log(`ready`); })()
内容的提问来源于stack exchange,提问作者Mario
相关产品推荐
相关产品推荐

