Saltar al contenido

async / await en Angular `ngOnInit`

Solución:

No es diferente de lo que tenías antes. ngOnInit devolverá una promesa y la persona que llama ignorará esa promesa. Esto significa que la persona que llama no esperará a que todo en su método termine antes de continuar. En este caso específico, significa que la vista terminará de configurarse y la vista podrá iniciarse antes this.data Está establecido.

Esa es la misma situación que tuviste antes. La persona que llama no esperará a que finalicen sus suscripciones y posiblemente iniciará la aplicación antes this.data había sido poblado. Si su punto de vista se basa en data entonces es probable que tengas algún tipo de ngIf setup para evitar que acceda a él.

Personalmente, no lo considero incómodo o una mala práctica, siempre y cuando sea consciente de las implicaciones. sin embargo, el ngIf puede ser tedioso (se necesitarían de cualquier manera). Personalmente, he pasado a usar resolutores de rutas donde tiene sentido para poder evitar esta situación. Los datos se cargan antes de que la ruta termine de navegar y puedo saber que los datos están disponibles antes de que se cargue la vista.

Ahora, obviamente, Angular no “sabrá” que ngOnInit se ha vuelto asíncrono. Siento que esto no es un problema: mi aplicación todavía funciona como antes.

Semánticamente se compilará bien y se ejecutará como se esperaba, pero la conveniencia de escribir async / wait tiene un costo de manejo de errores, y creo que debería evitarse.

Veamos lo que sucede.

Qué sucede cuando se rechaza una promesa:

public ngOnInit() {
    const p = new Promise((resolver, reject) => reject(-1));
}

Lo anterior genera el siguiente seguimiento de pila:

core.js:6014 ERROR Error: Uncaught (in promise): -1
    at resolvePromise (zone-evergreen.js:797) [angular]
    at :4200/polyfills.js:3942:17 [angular]
    at new ZoneAwarePromise (zone-evergreen.js:876) [angular]
    at ExampleComponent.ngOnInit (example.component.ts:44) [angular]
    .....

Podemos ver claramente que el error no manejado fue provocado por un ngOnInit y también ver qué archivo de código fuente encontrar la línea de código ofensiva.

¿Qué pasa cuando usamos async/wait eso es rechazar:

    public async ngOnInit() {
        const p = await new Promise((resolver, reject) => reject());
    }

Lo anterior genera el siguiente seguimiento de pila:

core.js:6014 ERROR Error: Uncaught (in promise):
    at resolvePromise (zone-evergreen.js:797) [angular]
    at :4200/polyfills.js:3942:17 [angular]
    at rejected (tslib.es6.js:71) [angular]
    at Object.onInvoke (core.js:39699) [angular]
    at :4200/polyfills.js:4090:36 [angular]
    at Object.onInvokeTask (core.js:39680) [angular]
    at drainMicroTaskQueue (zone-evergreen.js:559) [<root>]

¿Qué sucedió? No tenemos ni idea, porque el seguimiento de la pila está fuera del componente.

Aun así, es posible que tenga la tentación de usar promesas y simplemente evitar usar async / wait. Así que veamos qué sucede si se rechaza una promesa después de una setTimeout().

    public ngOnInit() {
        const p = new Promise((resolver, reject) => {
            setTimeout(() => reject(), 1000);
        });
    }

Obtendremos el siguiente seguimiento de pila:

core.js:6014 ERROR Error: Uncaught (in promise): [object Undefined]
    at resolvePromise (zone-evergreen.js:797) [angular]
    at :4200/polyfills.js:3942:17 [angular]
    at :4200/app-module.js:21450:30 [angular]
    at Object.onInvokeTask (core.js:39680) [angular]
    at timer (zone-evergreen.js:2650) [<root>]

Nuevamente, hemos perdido el contexto aquí y no sabemos a dónde ir para corregir el error.

Los observables sufren los mismos efectos secundarios del manejo de errores, pero generalmente los mensajes de error son de mejor calidad. Si alguien usa throwError(new Error()) los Error El objeto contendrá un seguimiento de pila, y si está utilizando el HttpModule los Error El objeto suele ser un Respuesta http objeto que le informa sobre la solicitud.

Entonces, la moraleja de la historia aquí: detecta tus errores, usa observables cuando puedas y no uses async ngOnInit(), porque volverá a perseguirlo como un error difícil de encontrar y corregir.

Puedes usar la función rxjs of.

of(this.service.getData());

Convierte la promesa en una secuencia observable.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *