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

如何在NgRx SignalStore中等待RxMethod的返回结果?

解决异步调用后获取Signal值的问题

你的核心问题在于getBankWidget()是异步操作,但你在调用后立即同步访问isWidgetLink$$(),此时异步请求还未完成,widgetBankLinks还没更新,导致链接为空。可以通过以下几种方式解决:

方案1:让getBankWidget()返回Observable,主动等待完成

首先修改UserApplication,让getBankWidget()返回异步操作的Observable,这样组件可以明确知道操作何时完成:

export class UserApplication {
  private readonly store = inject(CustomerStore);

  // 修改方法,返回rxMethod的Observable
  getBankWidget(): Observable<void> {
    return this.store.getBankWidget();
  }

  // 其余getter保持不变
  get isLinxoId(): Signal<boolean | null> {
    return this.store.isLinxoId;
  }

  get isWidget(): Signal<boolean | null> {
    return this.store.isWidget;
  }

  get customer(): Signal<Customer | null> {
    return this.store.customer;
  }
  get widgetBankLinks(): Signal<WidgetBankLinks | undefined> {
    return this.store.widgetBankLinks;
  }
}

然后在组件的addBank()方法中,通过订阅或async/await等待操作完成后再处理链接:

方式A:使用async/await

async addBank() {
  try {
    // 等待异步操作完成
    await this._customerApp.getBankWidget().toPromise();
    
    // 此时widgetBankLinks已更新,安全获取链接
    const connectionLink = this.isWidgetLink$$()?._links?.add_connection;
    if (connectionLink) {
      this.sanitizedWidgetLink = this._sanitizer.bypassSecurityTrustResourceUrl(connectionLink);
      this.showIframe = true;
    }
  } catch (error) {
    console.error('获取银行Widget失败:', error);
    // 这里可以添加错误提示逻辑
  }
}

方式B:使用Observable订阅

addBank() {
  this._customerApp.getBankWidget().subscribe({
    next: () => {
      const connectionLink = this.isWidgetLink$$()?._links?.add_connection;
      if (connectionLink) {
        this.sanitizedWidgetLink = this._sanitizer.bypassSecurityTrustResourceUrl(connectionLink);
        this.showIframe = true;
      }
    },
    error: (err) => {
      console.error('获取银行Widget失败:', err);
      // 错误处理逻辑
    }
  });
}

方案2:使用Effect响应式监听Signal变化

更符合Angular Signal响应式风格的做法是,用effect监听widgetBankLinks的变化,当它有有效值时自动处理链接:

export class AssetsComponent implements OnInit {
  private readonly _customerApp = inject(UserApplication);
  private readonly _sanitizer = inject(DomSanitizer);
  private readonly _effect = inject(EffectRef);

  isLinxoId$$ = this._customerApp.isLinxoId;
  isWidgetLink$$ = this._customerApp.widgetBankLinks;
  isWidget$$ = this._customerApp.isWidget;

  // 优化类型,避免any
  sanitizedWidgetLink: SafeResourceUrl | null = null;
  showIframe: boolean = false;

  ngOnInit(): void {
    if (!this.isLinxoId$$()) this._customerApp.createBankUser();

    // 监听widgetBankLinks的变化,自动处理链接
    this._effect(() => {
      const widgetLinks = this.isWidgetLink$$();
      const connectionLink = widgetLinks?._links?.add_connection;
      
      if (connectionLink) {
        this.sanitizedWidgetLink = this._sanitizer.bypassSecurityTrustResourceUrl(connectionLink);
        this.showIframe = true;
      } else {
        this.sanitizedWidgetLink = null;
        this.showIframe = false;
      }
    });
  }

  addBank() {
    // 只需触发异步请求,剩下的交给effect自动处理
    this._customerApp.getBankWidget();
  }
}

这种方式不需要手动管理异步流程,只要widgetBankLinks更新,effect就会自动执行,更简洁且符合Signal的设计理念。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 03:55:57