【问题标题】:How to properly create and resolve Observable of Observables (RxJS)如何正确创建和解析 Observable 的 Observable (RxJS)
【发布时间】:2020-07-26 14:16:29
【问题描述】:

在我的 Angular 应用程序中,我有多个相互依赖的服务。所以我为他们创建了一个依赖关系图。这是一个简短的示例:

let accountInitialization$: Observable<void>;
let productInitialization$: Observable<void>;

const dependenciesMap = {
  accountService: [],
  productService: [
    accountInitialization$ // There could be one or more dependencies
  ]
}

accountInitialization$ = this.getDependencies(dependenciesMap.accountService)
  .pipe(
    mergeMap(_ => {
      return this.accountService.initialize();
    })
  );

productInitialization$ = this.getDependencies(dependenciesMap.productService)
  .pipe(
    mergeMap(_ => {
      return this.productService.initialize();
    })
  );

accountInitialization$.subscribe(() => {
  this.progressUpdate.next(StartUpProgressUpdate.AccountsInitialized);
});

productInitialization$.subscribe(() => {
  this.progressUpdate.next(StartUpProgressUpdate.ProductsInitialized);
});

forkJoin([accountInitialization$, productInitialization$]).subscribe(
  () => {
    // do some work
  },
  error => {
    console.log(error); // This is where I see the error specified below
  }
);

所以 Product Service 依赖于 Account Service 的初始化。 getDependencies 函数如下所示:

private getDependencies(dependencies: Observable<void>[]) {
if (dependencies.length) {
  return forkJoin(dependencies);
}
return EMPTY;

}

我想在这个例子中实现的是,在初始化 Product Service 之前,确保首先初始化 Account Service。现在我收到此错误

错误类型错误:您在预期流的位置提供了“未定义”。您可以提供 Observable、Promise、Array 或 Iterable。

看起来.initialize() 函数从未被调用...

我不确定我在这里做错了什么。任何帮助将不胜感激,谢谢。

【问题讨论】:

    标签: angular typescript rxjs


    【解决方案1】:

    您必须使用switchMap,而不是使用forkJoin。我不知道如何构造它,但像这样:

    import { switchMap } from 'rxjs/operators';
    ...
    productInitialization$ = this.accountInitialization$.pipe(
      switchMap(accountInitializtion => {
        console.log('account initialization finished with: ', accountInitialization);
        // switch to this observable once complete
        return this.productService.initialize();
      });
    )
    

    对您来说可能会有所不同,但请查看 concatMapswitchMapmergeMap 以从一个 Observable 转到另一个。

    【讨论】:

    • 谢谢!这肯定简化了我的代码。但是,我仍然遇到同样的错误:ERROR TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. 我更新了帖子,提供了更多详细信息。
    • return this.accountService.initialize();return this.productService.initialize(); 是否返回 Observables?如果不是,那可能就是问题所在。 mergeMap 期望返回 Observable。并确保accountInitialization$productInitialization$ 也返回Observables
    • 是的,this.accountService.initialize() 返回一个 Observable&lt;void&gt;,productService 也是如此。 accountInitialization$productInitialization$ 也是 Observable&lt;void&gt;。当我尝试更多不同的事情时,我会及时通知你,谢谢你的帮助。
    • 对不起,我忘了添加更多细节。我的内部 observable 是一个被分叉的 observable 列表。
    • 我不确定您的意思,但您应该查看 tap 运算符进行调试。你基本上可以做tap(value =&gt; { console.log(value); debugger; }),,你可以调试流的每一步发生的事情。 rxjs-dev.firebaseapp.com/api/operators/tap
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多