简体   繁体   English

如何运行 observable 取决于先前在 Angular 中使用 RxJS 的 observable 结果?

[英]How to run observable depends on previous observable's result with RxJS in Angular?

I need to do these things:我需要做这些事情:

  • delete an item from remote server从远程服务器删除项目
  • if it's success, delete item from local storage如果成功,从本地存储中删除项目
  • if it's success, reload the items from remote server如果成功,从远程服务器重新加载项目

Now I have this code, but it's not working well, because the third step isn't run.现在我有了这个代码,但它运行得不好,因为第三步没有运行。

delete(model: T, paginate: PaginateInterface): Observable<any> {
  return this.remoteStorageService.delete(model).pipe(map((resultDelete: boolean) => {
    if (resultDelete) {
      this.localStorageService.delete(model);
      return this.remoteStorageService.getAll().pipe(map( (resultGetAll: PaginateInterface) => {
        return resultGetAll;
      }));
    }

    return paginate;
  }));
}

I tried to use RxJS switchMap function, but I'm totally lost.我尝试使用 RxJS switchMap 函数,但我完全迷失了。

How can I run a function depends on observable's result, and then another observable what return with results?我如何运行一个函数取决于 observable 的结果,然后另一个 observable 返回什么结果?

I assume steps 1 and 3 are the component's job and step 2 is the service's job.我假设第 1 步和第 3 步是组件的工作,第 2 步是服务的工作。

You can use the tap method to do extra logic on success or failure of an observable:您可以使用tap方法对 observable 的成功或失败执行额外的逻辑:

Service:服务:

deleteItem(model): Observable<any> {
  return this.http.delete<any>(`${yourUrl}`, model)
    .pipe(
      tap(result => {
        // success
        // delete from local storage here
      }, error => {
        // fail
        // in case you need logic for failure, put it here
      })
    );
}

Component:成分:

delete(model) {
  this.yourService.deleteItem(model)
    .subscribe(result => {
      // success, local storage is updated at this point
      // reload your data
    }, error => {
      // fail, local storage was not updated
      // do your error handling logic here
    });
}

If step 2 needs to be done in the component, simply move the pipe code to your component.如果需要在组件中完成第 2 步,只需将pipe代码移动到您的组件中即可。

From the code you posted and the comments I assume that remoteStorageService.delete and remoteStorageService.getAll() return some Observables while localStorageService.delete() returns void .根据您发布的代码和评论,我假设remoteStorageService.deleteremoteStorageService.getAll()返回一些 Observables 而localStorageService.delete()返回void

If this is the case you can try something like this如果是这种情况,您可以尝试这样的操作

delete(model: T, paginate: PaginateInterface): Observable<any> {
  return this.remoteStorageService.delete(model)
  .pipe(
     concatMap((resultDelete: boolean) => {
        if (resultDelete) {
           this.localStorageService.delete(model);
           return this.remoteStorageService.getAll();
        } else {
           return EMPTY  // if the delete fails you complete the Observable
           // you can also error here if you want to terminate the Observable with an error
        }
     })
  )
}

The key here is that first you execute remoteStorageService.delete and wait for the Observable to notify its result.这里的关键是先执行remoteStorageService.delete ,等待Observable通知结果。 The use of the operator concatMap ensures that the Observables contained within concatMap are executed (or more precisely subscribed) only after remoteStorageService.delete notifies its result.运算符concatMap的使用确保concatMap中包含的 Observable 仅在remoteStorageService.delete通知其结果后才执行(或更准确地说是订阅)。 You can use then the result of remoteStorageService.delete to decide whether to return remoteStorageService.getAll() or return EMPTY .然后您可以使用remoteStorageService.delete的结果来决定是返回remoteStorageService.getAll()还是返回EMPTY

In the first case, remoteStorageService.getAll() will be the Observable subscribed by the Component, in the second case EMPTY will be the Observable subscribed by the Component.在第一种情况下, remoteStorageService.getAll()将是组件订阅的 Observable,在第二种情况下, EMPTY将是组件订阅的 Observable。 EMPY is an Observable which does not emit anything and immediately terminates. EMPY是一个 Observable,它不发出任何东西并立即终止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM