Javascript rxjs可观测管道(取(1))与toPromise

Javascript rxjs可观测管道(取(1))与toPromise,javascript,angular,typescript,rxjs,observable,Javascript,Angular,Typescript,Rxjs,Observable,最近,我被转移到一个新项目中,该项目使用angular 6作为前端框架,使用spring作为REST服务 该项目已经开发了2年,我观察到几乎所有使用angular HttpClient发出的HTTP请求都通过管道从rxjs获取过滤器。所有RESTAPI只发出一个值。不需要手动取消和观察值的惰性属性 我的直觉是,使用toPromise()将是一种更好的编码方式 你的想法是什么 //customer-service.ts 构造函数(专用http:HttpClient){ } 公众客户(){ 返回ht

最近,我被转移到一个新项目中,该项目使用angular 6作为前端框架,使用spring作为REST服务

该项目已经开发了2年,我观察到几乎所有使用angular HttpClient发出的HTTP请求都通过管道从rxjs获取过滤器。所有RESTAPI只发出一个值。不需要手动取消和观察值的惰性属性

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

你的想法是什么

//customer-service.ts
构造函数(专用http:HttpClient){
}
公众客户(){
返回http.get('/customers');
}
//组件技术
公共ngOnInit(){
this.customerService.getCustomers().pipe(take(1)).subscribe((customers)=>{
//做点什么
})
}
我提议的办法:

//customer-service.ts
构造函数(专用http:HttpClient){
}
公共getCustomers():承诺{
返回http.get('/customers').toPromise();
}
//组件技术
公共ngOnInit(){
this.customerService.getCustomers()。然后((客户:数组)=>{
//做点什么
})
}

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

正如你提到的强类型,我们可以在可观察方法中做同样的事情


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
       });
  }


public getCustomers():可观察{
返回http.get('/customers');
}
//组件技术
公共ngOnInit(){
this.customerService.getCustomers()
.管道(取(1))
.订阅((客户:阵列)=>{
//做点什么
});
}
  • 对于具有单个HttpResponse的HttpRequest,您可以依赖于promise 接近
  • 但是具有多个响应的HttpRequest,例如进程/流 数据(blob)采用可观察的方法

尽量使用Observable,一旦你熟悉它,你就不会选择其他选项。试试看

从可观察到的转变为承诺是一种倒退

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

所以,不,你不应该使用
toPromise()
,而且不,你的方式并不是“更好”(这是一种自我意识,伙计!)

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

键入HTTP应答并不取决于端口或可观察对象,而是取决于开发人员自己。清洁是一个视角问题,我个人讨厌看到
toPromise()
s

您的解决方案的主要缺点是,一旦转换为承诺,您就不能再使用管道传输任何内容,从而降低了功能的通用性

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

无论如何,如果不是,我只依赖提供的代码,这将是正确的代码:

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

....

public ngOnInit() {
  this.customerService.getCustomers()
    .subscribe((customers) => {...})
}
public getCustomers(){
返回http.get('/customers');
}
....
公共ngOnInit(){
this.customerService.getCustomers()
.subscribe((客户)=>{…})
}

事实上,公认的答案是误导性的,它说,将可观察到的转化为承诺就像是倒退了一步。而是关于你的需求是什么。 如下列文件所述:

观察值区分链接和订阅。承诺只有.then()条款。这使得observables在创建复杂的转换配方供系统的其他部分使用时非常有用,而不会导致执行工作

toPromise()和take(1)(简称运算符first())之间的区别在于take(1)在发出第一个值后完成,而toPromise等待最后一个发出的值(等待可观察值完成,然后解析发出的最后一个值)

您可能会感兴趣的可观察订阅和承诺之间的另一个区别是,可观察订阅是可取消的,而承诺不是。作为一个具体的例子,假设您的API/客户需要时间,但您不再需要结果,然后导航到另一个页面,取消订阅将取消HTTP请求。

我建议继续使用可观察的方式。 为什么??因为以后更容易:

  • 为计划的功能构建未来的逻辑(如映射、筛选等)
  • 使用代码,因为混合使用这两种方法会使读/写更加困难

另一方面,你有权利,你的代码比别人的代码更具可读性,但你也可以将可观测值更改为与你的一样好(只需添加强类型),它仍然保持可观测值的功能性和一致性。

两者都是强类型,其余部分都使用Rx,所以不。可读性如何?您将预先输入
.pipe(取(1))。订阅()
。然后()
?计算速度方面的效率如何?你知道你也可以使用
pipe(take(1))
?您甚至不必
接受(1)
,因为http observable在发出后完成。所以它只是
subscribe
vs
然后
。但可观测的东西使用得更多,也更灵活。我明白。还有一个问题:如果“http observable在发出后完成”,我还需要在订阅时调用unsubscribe吗?不,您不需要。您可以保存订阅并使用
检查。isUnsubscribed
您自己。您甚至不必键入函数返回类型,它将从http推断。Yeah typescript将推断,但是为了可读性,我以前是手工编写的。你可以将鼠标悬停在方法上,然后你已经在
中明确地键入了它,所以我看不出有理由再键入两次。这是一个愚蠢的贬义评论。更好的类比是,如果你只需要一辆菲亚特,而继续驾驶一辆保时捷,当你不使用保时捷的所有功能时,它将花费你10倍的维护费用@乔治,请考虑一下