Should I use async and await with angular?

Angular Async Pipe: Din guide til renere kode

10/05/2016

Rating: 4.29 (1994 votes)

Angular-frameworket har en stærk forkærlighed for reaktiv programmering, især med det kraftfulde RxJS-bibliotek, som er en fast bestanddel af næsten ethvert Angular-projekt. For nye udviklere kan reaktiv programmering virke som en hjernevridende udfordring. Men når man først får styr på det, åbner der sig en verden af elegante løsninger. Dog medfører reaktiv programmering med RxJS sine egne unikke udfordringer, især når det kommer til håndtering af abonnementer på datastrømme.

What is angular async pipe?
That's where the async pipe in Angular emerges and toots its horn. What is the Angular async pipe? Angular's async pipe is a pipe that subscribes to an Observable or Promise for you and returns the last value that was emitted.

Har du nogensinde skrevet kode i din Angular-komponent, der ligner dette? $observable.subscribe(...), kun for senere at skulle huske at tilføje $observable.unsubscribe() i ngOnDestroy-livscykluskrogen? Hver gang vi manuelt abonnerer på en Observable, påtager vi os ansvaret for at afmelde abonnementet for at forhindre hukommelseslækager, også kendt som memory leaks. Dette kan hurtigt gøre koden rodet og fejlbehæftet. Men hvad nu hvis der fandtes en overlegen, indbygget måde at håndtere dette på direkte i vores skabeloner? Det er her, Angulars async pipe kommer ind i billedet som en sand helt.

Indholdsfortegnelse

Hvad er Angular Async Pipe?

Angulars async pipe er en specialiseret pipe, der gør det hårde arbejde for dig. Den abonnerer på en Observable eller en Promise og returnerer den seneste værdi, der er blevet udsendt. Hver gang en ny værdi udsendes, markerer async pipe automatisk komponenten, så Angulars change detection-mekanisme ved, at den skal tjekke for opdateringer i brugergrænsefladen.

Den største fordel er dog, at når komponenten bliver ødelagt (for eksempel når brugeren navigerer til en anden side), vil async pipe automatisk unsubscribe fra din Observable eller Promise. Dette eliminerer fuldstændigt behovet for manuel afmelding og reducerer risikoen for memory leaks markant. Kort sagt, den håndterer hele livscyklussen for dit abonnement på en ren og deklarativ måde.

Hvorfor skal du bruge Async Pipe?

Enhver erfaren Angular-udvikler vil anerkende værdien af async pipe. Her er de primære grunde til, at du bør integrere den i din daglige kodning:

  • Undgå Memory Leaks: Som nævnt er den automatiske afmelding den vigtigste funktion. Du behøver ikke længere at bekymre dig om at glemme at kalde unsubscribe().
  • Renere komponentkode: Ved at flytte abonnementslogikken til skabelonen bliver din TypeScript-klasse mere overskuelig. Den fokuserer udelukkende på forretningslogik i stedet for data-binding-mekanik.
  • Mindre boilerplate: Du slipper for at skulle implementere ngOnDestroy, oprette properties til at holde abonnementer og manuelt tildele værdier.
  • Forbedret Change Detection:async pipe fungerer problemfrit med OnPush change detection-strategien, hvilket kan give betydelige performanceforbedringer i store applikationer.

Sammenligning: Manuel Subscription vs. Async Pipe

For at illustrere forskellen tydeligt, lad os se på en direkte sammenligning mellem de to tilgange.

EgenskabManuel SubscriptionBrug af Async Pipe
AbonnementUdføres manuelt i .ts-filen med .subscribe().Håndteres automatisk i HTML-skabelonen.
Afmelding (Unsubscribe)Skal kaldes manuelt i ngOnDestroy(). Let at glemme. sker automatisk, når komponenten ødelægges.
KodekompleksitetHøjere. Kræver mere kode (boilerplate) for at håndtere livscyklussen.Lavere. Koden er mere deklarativ og lettere at læse.
Change Detection (OnPush)Kræver manuelt kald af ChangeDetectorRef.markForCheck().Fungerer problemfrit uden ekstra kode.

Sådan bruges Async Pipe: Praktiske eksempler

Lad os dykke ned i nogle kodeeksempler for at se, hvordan async pipe fungerer i praksis.

Should I use async pipe?
Async pipe, on the other hand works just fine with that. That is why you should definitely use the async pipe wherever possible. Of course, interpolation is not the only data binding the async pipe can be used with.

Eksempel 1: Simpel Observable med en timer

Her opretter vi en Observable, der udsender et nyt tal hvert sekund. Ved hjælp af async pipe kan vi vise den aktuelle værdi direkte i vores skabelon.

// timer.component.ts import { Component } from '@angular/core'; import { Observable, timer } from 'rxjs'; @Component({ selector: 'app-timer', template: `<h3>Tæller: {{ timer$ | async }}</h3>` }) export class TimerComponent { timer$: Observable<number> = timer(0, 1000); } 

I dette eksempel er der ingen subscribe eller ngOnDestroy i vores komponentklasse. Al logik er indeholdt i skabelonen, hvilket gør komponenten utrolig simpel.

Eksempel 2: Brug med *ngIf for at håndtere null-værdier

En meget almindelig og kraftfuld måde at bruge async pipe på er i kombination med *ngIf. Dette lader os vente på, at data er tilgængelige, før vi forsøger at rendere dem. Ved at bruge as-syntaksen kan vi gemme resultatet i en lokal skabelonvariabel og genbruge den.

// user.component.ts import { Component } from '@angular/core'; import { Observable, of } from 'rxjs'; import { delay } from 'rxjs/operators'; interface User { name: string; email: string; } @Component({ selector: 'app-user', template: ` <div *ngIf="(user$ | async) as user; else loading"> <h3>Bruger: {{ user.name }}</h3> <p>Email: {{ user.email }}</p> </div> <ng-template #loading> <p>Indlæser brugerdata...</p> </ng-template> ` }) export class UserComponent { user$: Observable<User>; constructor() { // Simulerer et API-kald, der tager 2 sekunder this.user$ = of({ name: 'Jens Hansen', email: '[email protected]' }).pipe(delay(2000)); } } 

Denne tilgang er yderst effektiv. Den viser en "loading"-besked, mens data hentes. Når user$ Observable udsender en værdi, bliver *ngIf sand, og brugerdataene vises. Variabelen user kan genbruges uden at skulle anvende async pipe flere gange, hvilket ville skabe flere unødvendige abonnementer.

Eksempel 3: Brug med *ngFor til at vise lister

async pipe er også perfekt til at håndtere lister af data, der kommer fra en Observable. Her er et eksempel, hvor vi viser en liste af produkter.

What is angular async pipe?
That's where the async pipe in Angular emerges and toots its horn. What is the Angular async pipe? Angular's async pipe is a pipe that subscribes to an Observable or Promise for you and returns the last value that was emitted.
// products.component.ts import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; interface Product { id: number; name: string; price: number; } @Component({ selector: 'app-products', template: ` <h2>Vores Produkter</h2> <ul *ngIf="products$ | async as products"> <li *ngFor="let product of products"> {{ product.name }} - {{ product.price }} kr. </li> </ul> ` }) export class ProductsComponent { products$: Observable<Product[]>; constructor(private http: HttpClient) { this.products$ = this.http.get<Product[]>('/api/products'); } } 

Her henter vi en liste af produkter via HttpClient, som returnerer en Observable. I skabelonen bruger vi async pipe til at udpakke arrayet og *ngFor til at iterere over det og vise hvert produkt.

Ofte Stillede Spørgsmål (FAQ)

Erstatter async pipe fuldstændigt behovet for .subscribe()?

For data, der skal vises i skabelonen, er async pipe næsten altid den bedste løsning. Der er dog situationer, hvor du stadig har brug for .subscribe() i din komponentklasse. Dette er typisk, når du skal udføre en handling baseret på en Observables værdi, f.eks. at navigere til en ny side, vise en notifikation eller kalde en anden service. I disse tilfælde handler det om sideeffekter, ikke om databinding.

Hvad sker der, hvis min Observable kaster en fejl?

Hvis en Observable, der er bundet med async pipe, kaster en fejl, vil fejlen blive propageret, og async pipe vil ikke vise nogen værdi. Applikationen kan potentielt gå ned, hvis fejlen ikke håndteres. Det er god praksis at håndtere fejl i din Observable-pipeline ved hjælp af RxJS-operatorer som catchError, før data når skabelonen. Med catchError kan du f.eks. returnere en ny Observable med en standardværdi eller logge fejlen.

Kan jeg bruge async pipe med en Promise?

Ja, absolut. async pipe fungerer lige så godt med Promises som med Observables. Når du bruger den på en Promise, vil den vente på, at Promisen bliver resolved, og derefter vise den resolvede værdi. Den håndterer også automatisk oprydning.

// promise.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-promise', template: `<p>Besked fra Promise: {{ promise | async }}</p>` }) export class PromiseComponent { promise: Promise<string>; constructor() { this.promise = new Promise(resolve => { setTimeout(() => { resolve('Her er den forsinkede besked!'); }, 3000); }); } } 

Konklusion

Angulars async pipe er et essentielt værktøj for enhver udvikler, der arbejder med reaktiv programmering. Ved at automatisere håndteringen af abonnementer og afmeldinger gør den din kode markant renere, mere sikker og lettere at vedligeholde. Den eliminerer en hel klasse af potentielle fejl relateret til memory leaks og reducerer mængden af boilerplate-kode i dine komponenter. Ved at omfavne async pipe kan du skrive mere robuste og effektive Angular-applikationer og fokusere på det, der virkelig betyder noget: at bygge fantastiske brugeroplevelser.

Hvis du vil læse andre artikler, der ligner Angular Async Pipe: Din guide til renere kode, kan du besøge kategorien Sundhed.

Go up