rxjs observable.pipe(take(1))与toPromise

时间:2019-05-29 10:46:57

标签: javascript angular typescript rxjs observable

最近我已经转到了一个新项目,该项目使用angular 6作为前端框架和REST服务的源泉。

该项目正在进行2年的开发,我观察到的是,几乎所有使用Angular HttpClient发出的HTTP请求都通过管道传输以从rxjs中获取过滤器。所有REST API仅发出一个值。无需手动取消和观测对象的惰性。

我的直觉是,使用toPromise()将是更好的编码方式。

您有什么想法?

  //customer-service.ts
  constructor(private http: HttpClient) {

  }

  public getCustomers() {
     return http.get('/customers');
  }

  //component.ts
  public ngOnInit() {
      this.customerService.getCustomers().pipe(take(1)).subscribe((customers) => {
           //do some stuff
      })
  }

我建议的方法:

  //customer-service.ts
  constructor(private http: HttpClient) {

  }

  public getCustomers() : Promise<Array<Customer>> {
     return http.get('/customers').toPromise();
  }

  //component.ts
  public ngOnInit() {
      this.customerService.getCustomers().then((customers: Array<Customer>) => {
         //do some stuff
      })
  }

我认为我的方法更好,因为它是强类型且更干净。

4 个答案:

答案 0 :(得分:5)

实际上,接受的答案是误导,说将可观察对象转换为承诺就像退后一步。而是关于您的需求。 如Angular Documentation所述:

<块引用>

Observable 区分链接和订阅。 Promise 只有 .then() 子句。这使得 observable 可用于创建复杂的转换配方以供系统的其他部分使用,而不会导致工作被执行。

而 toPromise() 和 take(1)(或简称为 operator first())的区别在于,take(1) 在第一个值发出后完成,而 toPromise 等待最后发出的值(等待要完成的 observable 然后解析最后发出的值)。

您可能会感兴趣的 observable 和 promise 之间的另一个区别是,Observable 订阅是可取消的,而 Promise 则不可取消。举一个具体的例子,假设您的 API /customers 需要时间,但您不再需要结果并导航到另一个页面,取消订阅会取消 HTTP 请求。

答案 1 :(得分:1)

从可观察到可实现的承诺又退了一步。

这就像从保时捷911到菲亚特multipla。

因此,不,您不应该使用toPromise(),不,您的方式不会“更好”(那是我的伙伴!)

  

我认为我的方法更好,因为它是强类型且更干净。

键入HTTP答案并不依赖于形式或可观察性,而取决于开发人员本人。更清洁的观点是一个问题,我个人不喜欢看到toPromise()

该解决方案的主要缺点是,一旦转换为承诺,就无法再传递任何内容,从而使功能的通用性降低。

但是他们的代码也不是最好的。通常,这种行为用于存储和缓存,您确定没有遗漏吗?

无论如何,如果没有的话,我仅依靠提供的代码,这将是正确的代码:

public getCustomers() {
  return http.get<Customer[]>('/customers');
}

....

public ngOnInit() {
  this.customerService.getCustomers()
    .subscribe((customers) => {...})
}

答案 2 :(得分:0)

正如您提到的强类型输入一样,我们可以采用可观察的方法进行同样的操作。


public getCustomers():Observable<Array<Customer>>  {
     return http.get<Array<Customer>>('/customers');
  }

  //component.ts
  public ngOnInit() {
      this.customerService.getCustomers()
      .pipe(take(1))
      .subscribe((customers: Array<Customer>) => {
       //do some stuff
       });
  }

  • 对于具有单个HttpResponse的HttpRequest,您可以依赖 promise 方法。
  • 但是具有多个响应的HttpRequest,例如进度/流 data(blob)用于 Observable 方法。

尝试尽可能多地使用Observable,一旦熟悉就不会再使用其他选项。因此,请尝试一下!

答案 3 :(得分:0)

我建议继续使用 Observable 方式。

为什么?因为以后会更容易:

  • 为计划中的功能构建即将到来的逻辑(如映射、过滤等)
  • 使用代码,由于混合使用这两种方法会使读/写变得更加困难

另一方面你是对的,你的代码比其他人的代码更具可读性,但你也可以将 Observable 更改为和你的一样好(只需向它添加强类型),它仍然保持功能和 Observable 的一致性。