【问题标题】:Angular 2 emit when Http has finished to subsequently run another function当 Http 完成以随后运行另一个函数时,Angular 2 发出
【发布时间】:2016-06-28 12:06:43
【问题描述】:

我有一个通用函数来对我的 API 进行 DELETE 调用。函数是这样的:

deleteItem(url, item, action) {
    return this.http.delete(url)
        .subscribe(
            () => this.store.dispatch({ type: action, payload: item }),
            error => this.errorHandler(error),
            () => console.debug('Delete complete')
        )
    ;

我从几个地方调用这个函数,发送不同的 url、项目和操作。假设我有一个这样的函数:

deleteBookcase(bookcase) {
    this.apiService.deleteItem(BOOKCASE_URL, bookcase, BOOKCASE_REMOVE);
}

有时,我想在从 API 中删除项目后触发另一个操作。例如,也许我想检查我的全球书店是否发生了变化,现在我移除了书柜。

有没有一种简单的方法可以让我的deleteBookcase 函数知道 HTTP 调用和后续操作已经完成,然后才过早触发额外的操作?

【问题讨论】:

    标签: angular ngrx


    【解决方案1】:

    deleteItem() 中使用map() 而不是subscribe()

    deleteItem(url, item, action) {
        return this.http.delete(url)
            .map(() => this.store.dispatch({ type: action, payload: item })
            .catch((error) => this.errorHandler(error))
            .do(() => console.debug('Delete complete'))
     });
    }
    

    并在您拨打deleteItem()的地方订阅

    deleteBookcase(bookcase) {
        this.apiService.deleteItem(BOOKCASE_URL, bookcase, BOOKCASE_REMOVE)
        .subscribe(data => doSomething());
    }
    

    别忘了导入domapcatch

    【讨论】:

    • 为什么使用map()而不是do()触发商店调度?
    • 我并没有打算关闭代码正在做什么。如果结果应该转发给订阅者,你需要map(),如果你只想调用一个调用而不关心结果或在domap回调中处理结果,那么@ 987654335@ 更合适。如果调用返回一个 observable,那么 flatMap() 可能更合适。
    【解决方案2】:

    为此,我会以这种方式重构您的方法:

    deleteItem(url, item, action) {
      return this.http.delete(url)
          .catch((error) => {
            // handle error
          })
          .do(() => {
            this.store.dispatch({ type: action, payload: item });
          });
    }
    
    deleteBookcase(bookcase) {
        this.apiService.deleteItem(BOOKCASE_URL, bookcase, BOOKCASE_REMOVE).subscribe(() => {
          // do something
        });
    }
    

    如果操作在异步数据流之外执行,请使用 do 运算符。如果您想在对 dispatch 的调用结束后通知(并返回一个 observable),您可以使用 flatMap 之一:

    deleteItem(url, item, action) {
      return this.http.delete(url)
          .catch((error) => {
            // handle error
          })
          .flatMap(() => {
            return this.store.dispatch({ type: action, payload: item });
          });
    }
    

    通过这种方式重构你的方法,你需要小心,因为 observables 是惰性的,所以在没有订阅的情况下调用 deleteItem 将不会执行请求:

    // Request isn't executed
    this.deleteItem();
    
    // Request is executed
    this.deleteItem().subscribe(() => {
    });
    

    【讨论】:

    • 那么如果我在deleteBookcase 函数中使用了this.apiService.deleteItem().subscribe(() => something()),那么一旦deleteBookcase 执行完毕,订阅会被销毁吗?
    • 事实上是的,因为 HTTP observables 是一次性的。我的意思是只触发了一个事件:响应。
    猜你喜欢
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 1970-01-01
    • 2017-03-18
    相关资源
    最近更新 更多