You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何等待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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 14:27:00