javascript - rxjs observable.pipe(take(1)) vs toPromise
Nylig har jeg blitt overført til et nytt prosjekt som bruker Angular 6 som frontend-rammeverk og Spring for REST-tjenester.
Prosjektet har vært under utvikling i 2 år nå, og det jeg har observert er at nesten alle HTTP-forespørsler gjort med Angular HttpClient deretter pipe'es til take filter fra rxjs. Alle REST API-er sender bare én verdi. Det er ikke behov for manuell kansellering og den late egenskapen til observables.
Min intuisjon er at å bruke toPromise() ville være en bedre måte å kode på.
Hva er dine tanker?
//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
})
}
Min foreslåtte tilnærming:
//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
})
}
Jeg synes at min tilnærming er bedre fordi den er sterkt typet og den er renere.
Svar #1
Faktisk er det aksepterte svaret misvisende ved å si at å transformere en observable til et løfte er som å ta et skritt tilbake. Det handler heller om hva dine behov er, som angitt i Angular-dokumentasjonen:
Observables skiller mellom kjeding og abonnement. Løfter har bare .then()-klasser. Dette gjør observables nyttige for å lage komplekse transformasjonsoppskrifter som kan brukes av andre deler av systemet, uten å få arbeidet til å bli utført.
Og forskjellen mellom toPromise() og take(1) (eller kort sagt bruk operatoren first()), er at take(1) fullfører etter den første verdien som sendes ut, mens toPromise venter på den siste sendte verdien (venter på at observable skal fullføre og deretter løser den siste sendte verdien).
En annen forskjell mellom observables og promises som kan interessere deg, er at Observable-abonnementer kan avbestilles, mens promises ikke kan det. Som et konkret eksempel, si at API-et ditt /customers tar tid, men du ikke trenger resultatene lenger og navigerer til en annen side; å avslutte abonnementet avbryter HTTP-forespørselen.
Svar #2
Som du nevnte, sterkt typet, kan vi gjøre det samme i en observerbar tilnærming.
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
});
}
- For HttpRequest med enkelt HttpResponse kan du stole på promise-tilnærming.
- Men HttpRequest med flere responser, slik som progress/stream av data(blob), bør bruke Observable-tilnærmingen.
Prøv å bruke Observable så mye som mulig, når du blir kjent med det vil du ikke velge andre alternativer. Så prøv det!
