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

如何检测Apollo GraphQL订阅成功启动?基于graphql-ws与Observable

解决GraphQL订阅启动状态检测问题

核心思路

graphql-ws的订阅成功确认(服务器返回订阅接受响应)不会通过next回调触发,而是在订阅建立完成时会触发内部的ready信号。我们可以扩展client.subscribe的回调逻辑,在订阅成功建立时手动resolve Promise,同时保留原Observable的事件监听能力。

修改后的代码实现

function subscribeAndWaitForReady(operation) {
  return new Promise((resolve, reject) => {
    const observable = new Observable((observer) => {
      const unsubscribe = client.subscribe(operation, {
        next: (data) => observer.next(data),
        error: (err) => {
          observer.error(err);
          reject(err); // 订阅启动失败时reject Promise
        },
        complete: () => observer.complete(),
        // 关键:监听graphql-ws的ready事件,确认订阅已成功启动
        ready: () => {
          resolve(observable); // 订阅就绪后resolve,返回Observable供后续事件监听
        },
      });

      return unsubscribe;
    });
  });
}

使用示例

// 显示订阅启动进度条
showLoadingProgress();

try {
  const subscriptionObservable = await subscribeAndWaitForReady({
    query: YOUR_SUBSCRIPTION_QUERY,
    variables: {},
  });
  // 订阅启动成功,隐藏进度条
  hideLoadingProgress();

  // 开始监听后续推送的事件
  const unsubscribe = subscriptionObservable.subscribe({
    next: (data) => console.log('收到事件:', data),
    error: (err) => console.error('订阅运行时错误:', err),
    complete: () => console.log('订阅结束'),
  });

  // 需取消订阅时调用
  // unsubscribe();
} catch (err) {
  // 订阅启动失败,隐藏进度条并处理错误
  hideLoadingProgress();
  console.error('订阅启动失败:', err);
}

说明

  • graphql-ws的subscribe回调原生支持ready事件,该事件会在服务器确认订阅成功建立时触发,恰好作为Promise的resolve时机。
  • Promise的resolve值设为创建好的Observable,确保订阅启动成功后,能继续通过Observable监听后续的事件推送。
  • 订阅启动阶段的错误会通过error回调触发并reject Promise,便于统一处理启动失败场景。

内容的提问来源于stack exchange,提问作者A.A

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 02:02:36