Articles

Una introducción rápida a «Promises» y»Async/Await»(con nuevas características)

Una promesa es una instancia (objeto) de la clase Promise (constructor). Para crear una promesa, usamos la sintaxis new Promise(executor) y proporcionamos una función de ejecutor como argumento. Esta función ejecutora proporciona un medio para controlar el comportamiento de nuestra resolución de promesa o rechazo.

En TypeScript, podemos proporcionar el tipo de datos del valor devuelto cuando se cumple la promesa. Dado que el error devuelto por la promesa puede tomar cualquier forma, el tipo de datos predeterminado del valor devuelto cuando se rechaza la promesa se establece en any por el TypeScript.

Para anotar el tipo de valor de resolución de la promesa, utilizamos una declaración de tipo genérico. Básicamente, prometes un tipo con Promise constructor en forma de new Promise<Type>() que indica el tipo de valor resuelto de la promesa. Pero también puede usar la sintaxis let p: Promise<Type> = new Promise() para lograr lo mismo.

have Hemos discutido las clases de genéricos en detalle en la lección de genéricos.

(promesa.ts)

En el ejemplo anterior, findEvenes una promesa que se creó utilizando el constructor Promise que se resuelve después de 1 segundo. El tipo de datos resuelto de esta promesa es number, por lo que el compilador TypeScript no le permitirá llamar a la función resolve con un valor que no sea un valor de tipo number number.

El tipo predeterminado del valor de rechazo de la promesa es any, por lo que llamar a la función reject con cualquier valor es legal. Este es el comportamiento predeterminado de TypeScript, y puede encontrar el hilo de discusión aquí si tiene sus propias opiniones.

Dado que hemos proporcionado el number como el tipo de datos de resolución promise exitosa, el compilador TypeScript proporcionará el number type al argumento de value argumento de then método de devolución de llamada.

La devolución de llamada proporcionada en el método then se ejecuta cuando se resuelve la promesa y la devolución de llamada proporcionada en el método catch se ejecuta cuando rechaza o algún error al resolver la promesa. El método finally registra una devolución de llamada que se ejecuta cuando promise resuelve o rechaza.

Si el compilador de TypeScript se queja del método finally, significa que el compilador de TypeScript no importa definiciones de tipo para el método finally. Este método se introdujo en ES2016, por lo que es bastante nuevo. Otras características de Promise API utilizadas en esta lección son bastante nuevas, por lo tanto, asegúrese de que su archivo tsconfig.json tenga cargadas todas las bibliotecas nuevas.

(tsconfig.json)

En mi tsconfig.json, he cargado el ES2020 biblioteca estándar. Esto proporciona soporte para todas las funciones de JavaScript hasta ES2020. Si desea obtener más información sobre el archivo tsconfig.json o las bibliotecas estándar, lea la lección de compilación (próximamente).

la Promesa de Encadenamiento

El thencatch y finally métodos devuelven una promesa implícita. Cualquier valor devuelto por estas funciones de devolución de llamada se envuelve con una promesa y se devuelve, incluido undefined. Esta promesa implícita se resuelve por defecto a menos que devuelva deliberadamente una nueva promesa de estos métodos que podría fallar.

por lo tanto usted puede anexar thencatch o finally métodos para ninguna de las anteriores thencatch o finally método. Si una promesa implícita es devuelta por uno de estos métodos, entonces el tipo de valor resuelto de esta promesa implícita es el tipo del valor devuelto. Veamos un ejemplo rápido.

(promesa de encadenamiento.ts)

Hemos modificado el ejemplo anterior y agregó otro then método para el primer then método. Desde el primer then método devuelve un valor de tipo string, la promesa implícita que devuelve este método se resolverá con un valor del tipo string. Por lo tanto, el segundo then método recibirá value argumento de tipo string como se puede ver en los resultados.

Promesa.resolver

La llamadaresolve el método estático de la llamadaPromise devuelve una promesa que ya se ha resuelto correctamente con un valor que proporcionó en la llamadaPromise.resolve(value). Esto es más fácil que crear una nueva instancia de la llamada Promise y agregar lógica para resolver la promesa de inmediato.

(la promesa de resolver.ts)

Como puede ver en los resultados anteriores, la promesa devuelta por la llamada Promise.resolve(value) siempre se resuelve inmediatamente con un valor number desde el valor value el argumento tiene el tipo de number.

Promesa.rechazar

Similar al método estático Promise.resolve, el método Promise.reject(error) siempre devuelve una promesa rechazada. El valor del rechazo de promesa se toma del argumento error y su tipo es any.

(promesa de rechazar.ts)

El tipo de promesa devuelta por el método Promise.reject es Promise<never> porque esta promesa nunca se resuelve, por lo que no habrá ningún valor de resolución de promesa. Por lo tanto, el valor del tipo resuelto por la promesa es nevernever significa el valor que nunca se produce.

Promesa.todos

En algunos escenarios, se trata de múltiples promesas. Si desea ejecutar una función de devolución de llamada cuando todas las promesas se resuelvan correctamente, utilice el método estático Promise.all.

var pAll = Promise.all()pAll.then( ( ) => {___});

El método Promise.all toma una matriz (iterable con precisión) de promesas y devuelve una nueva promesa. La promesa devuelta pAll se resuelve cuando todas las promesas p1, p2, ... se resuelven con éxito. Esta promesa se resuelve con un valor de matriz que contiene los valores de resolución de promesa de p1, p2, ... en el orden de aparición.

(promesa-todos los.ts)

Como puede ver en el ejemplo anterior, el método Promise.all es genérico y toma el tipo el valor resuelto por cada promesa que se le proporciona. Proporcionar un tipo genérico es bastante útil cuando estamos utilizando el valor resuelto de esta promesa colectiva, como se puede ver en el resultado anterior.

Most La mayoría de los métodos estáticos de la clase Promise son genéricos, como se muestra en los ejemplos siguientes.

Hay una salvedad con la etiqueta Promise.all. Implementa el mecanismo de falla rápida, lo que significa que si alguna de las promesas de entrada p1, p2, ... es rechazada, pAll es rechazada. If no esperará a que se resuelvan otras promesas pendientes.

(promesa-todos-rechazar.ts)

Como puede ver en el resultado anterior, como la 3ª promesa fue rechazada justo después de 1 segundo, el allPromise fue rechazado inmediatamente.

Promesa.allSettled

El método estático Promise.allSettled es similar a Promise.allpero a diferencia de Promise.all, espera hasta que todas las promesas se resuelvan (lo que significa hasta que se resuelvan o rechacen). Por lo tanto, la promesa devuelta por Promise.allSettled nunca se rechazará (pero hemos agregado el bloque catch en el siguiente ejemplo).

(promesa-todos resuelto.ts)

Trabajar con la etiqueta promise.allSettled puede ser un poco abrumador como usted puede, desde el programa anterior y su resultado. En primer lugar, el método allSettle devuelve una promesa que se resuelve con un array de valores PromiseSettledResult<type> cuando se establecen todas las promesas. El type se deriva del tipo de la promesa de entrada. El tipo PromiseSettledResult se ve como a continuación.

Estos tipos son proporcionados por la biblioteca estándar de TypeScript. Por lo tanto, cuando se resuelve una promesa, el método allSettled convierte su valor en forma PromiseFulfilledResult y cuando falla, lo convierte en forma PromiseRejectedResult. Es por eso que cuando se resuelve allSettled, es una matriz de objetos en la que cada objeto tiene una forma de interfaz PromiseFulfilledResult o PromiseRejectedResult.

Desde PromiseFulfilledResult es una unión de PromiseFulfilledResult y PromiseRejectedResult que tiene en común status propiedad de los literales de tipo de datos, podemos utilizar como un discriminante en el switch/case guardia.

have Hemos hablado de switch/case protección de tipos y uniones discriminatorias en la lección del Sistema de tipos.

(promesa-todos resuelto.ts)

Promise.race

El Promise.race toma un array (iterable con precisión) de promesas y devuelve una nueva promesa que resuelve o rechaza tan pronto como una de las promesas de entrada resuelve o rechaza. En otras palabras, la promesa devuelta por Promise.race se liquida con el resultado de una de las promesas de entrada que se liquida rápidamente.

(promesa de la carrera.ts)

A diferencia de Promise.all o Promise.allSettled, este método solo devuelve un valor único de la primera promesa establecida, por lo que el tipo de promesa devuelta es Promise<number> en el caso anterior. Desde que la primera promesa se estableció primero entre otras, elthen callback de fastestPromise se llama después de 500 ms con el valor de la promesa resuelta.

The El nuevo método Promise.any() ha alcanzado la etapa 4 de la pista de propuesta ECMAScript. Promise.any es muy parecido a Promise.race pero espera hasta que la primera promesa se resuelva correctamente. Este método lanza una excepción AggregateError si se rechazan todas las promesas.