Explicación detallada de TypeScript Promise

Promise es la base de la programación asíncrona en JavaScript, y TypeScript ofrece soporte completo de tipos para Promise.

A través de parámetros genéricos, se pueden especificar con precisión los tipos del valor de resolución y del valor de rechazo de una Promise.


Diagrama SVG: flujo de trabajo de Promise Fondo Título Flujo de trabajo de Promise Crear Promise Crear Promise new Promise((resolve, reject) => {...}) Flecha pending Pendiente Rama: resolve/reject fulfilled ✓ rejected ✗ Parte inferior: métodos then() · catch() · finally() Marcador de flecha

Por qué necesitamos Promise

En JavaScript, muchas operaciones son asíncronas, como peticiones de red, lectura de archivos, temporizadores, etc.

Promise proporciona una interfaz unificada de programación asíncrona, lo que facilita la escritura y gestión del código asíncrono.

TypeScript, mediante el soporte de genéricos, garantiza la seguridad de tipos de Promise.

Explicación del concepto:Promise es un objeto que representa el resultado final de una operación asíncrona. Tiene tres estados: pending (en curso), fulfilled (cumplida) y rejected (rechazada).


Crear Promise

Se crea una Promise utilizando el constructor de Promise, pasando una función ejecutora.

Ejemplo

// Crear una Promise, usando genéricos para especificar el tipo del valor resuelto
// Promise<string> indica que devuelve un string al tener éxito
var promise = new Promise<string>(function(resolve, reject) {
    var success = true;
    if (success) {
        // Llamar a resolve indica que la operación tuvo éxito, pasando el valor resultante
        resolve(¡Éxito!);
    } else {
        // Llamar a reject indica que la operación falló, pasando el error
        reject(new Error(Fallo));
    }
});

// Usar then para manejar el caso de éxito
promise.then(function(value) {
    console.log(Completado: + value);
})["catch"](function(error) {
    // Usar catch para manejar el caso de error
    console.log(Error: + error.message);
});

Resultado de la ejecución:

Completado: ¡Éxito!

Explicación de los genéricos:Promise<T>La T en Promise<T> es el tipo del valor cuando la Promise se resuelve con éxito. Esto permite a TypeScript inferir el tipo del valor de retorno.


Llamadas en cadena de Promise

Los métodos then y catch devuelven una nueva Promise, por lo que se pueden encadenar.

Ejemplo

// Llamada en cadena: cada then devuelve un nuevo valor, que es recibido por el siguiente then
var promise = Promise.resolve(1)
    .then(function(n) {
        // Primer then, n = 1
        return n * 2;  // Devuelve 2
    })
    .then(function(n) {
        // Segundo then, n = 2
        return n + 10;  // Devuelve 12
    })
    .then(function(n) {
        // Tercer then, n = 12
        console.log(Resultado final: + n);
        return n;
    });

console.log(Cadena de Promise: + promise);

Resultado de la ejecución:

最终结果: 12
Promise 链: [object Promise]

Llamada en cadena:Cada then devuelve una nueva Promise, lo que nos permite ejecutar varias operaciones asíncronas en orden.


Promise.all

Promise.all espera a que todas las Promises se completen y devuelve un array con todos los resultados.

Ejemplo

// Crear tres Promises
var p1 = Promise.resolve(1);
var p2 = Promise.resolve(2);
var p3 = Promise.resolve(3);

// Promise.all espera a que todas las Promises se completen
// Devuelve un array con los resultados de todas las Promises
Promise.all([p1, p2, p3]).then(function(results) {
    console.log(Todo completado: + results);
    // Calcular la suma total
    console.log(Suma total: + results.reduce(function(a, b) { return a + b; }, 0));
});

Resultado de la ejecución:

全部完成: 1,2,3
总和: 6

Nota:Si alguna Promise falla, Promise.all se rechaza inmediatamente, sin esperar a que las demás se completen.


Promise.race

Promise.race devuelve el resultado de la Promise que se complete primero (ya sea con éxito o con error).

Ejemplo

// Crear tres Promises con diferentes retardos
var p1 = new Promise(function(resolve) {
    setTimeout(function() { resolve("p1"); }, 100);
});
var p2 = new Promise(function(resolve) {
    setTimeout(function() { resolve("p2"); }, 50);
});
var p3 = new Promise(function(resolve) {
    setTimeout(function() { resolve("p3"); }, 30);
});

// Promise.race devuelve el resultado de la Promise que se complete primero
Promise.race([p1, p2, p3]).then(function(value) {
    console.log(Primero en completarse: + value);
});

Resultado de la ejecución:

最先完成: p3

Casos de uso:Promise.race se usa a menudo para implementar tiempos de espera: se hace competir una Promise de operación larga con una Promise de timeout.


Promise.allSettled

Promise.allSettled espera a que todas las Promises terminen (tengan éxito o no) y devuelve el estado y resultado de cada Promise.

Ejemplo

// Crear tres Promises, una de las cuales fallará
var p1 = Promise.resolve(Éxito);
var p2 = Promise.reject(new Error(Fallo));
var p3 = Promise.resolve(Completado);

// Promise.allSettled espera a que todas las Promises terminen
// Devuelve el estado y el valor/reason de cada Promise
Promise.allSettled([p1, p2, p3]).then(function(results) {
    results.forEach(function(result, index) {
        if (result.status === "fulfilled") {
            console.log("Promise " + index + ": " + result.value);
        } else {
            console.log("Promise " + index + ": " + result.reason.message);
        }
    });
});

Resultado de la ejecución:

Promise 0: 成功
Promise 1: 失败
Promise 2: 完成

Diferencia:Promise.all se detiene inmediatamente ante el primer fallo; Promise.allSettled espera a que todas las Promises terminen.


Anotación de tipos de Promise

El soporte de genéricos de TypeScript hace que las declaraciones de tipos de Promise sean precisas.

Ejemplo

// Definir una función que devuelve una Promise
// Promise<{ name: string; age: number }> especifica el tipo del objeto de usuario devuelto
function getUser(): Promise<{ name: string; age: number }> {
    return Promise.resolve({ name: "Alice", age: 25 });
}

// función async: devuelve implícitamente una Promise
async function main() {
    // await infiere automáticamente el tipo de user
    var user = await getUser();
    console.log(Usuario: + JSON.stringify(user));
}

main();

Inferencia de tipos:TypeScript infiere automáticamente el tipo de retorno de la Promise según los parámetros genéricos, lo que nos permite obtener sugerencias de tipos completas también en async/await.


Consideraciones

  • Parámetros genéricos:Especifica siempre el parámetro genérico al usar Promise, para definir de forma clara el tipo de retorno.
  • Manejo de errores:Recuerda usar catch para manejar los casos en que la Promise falla.
  • all vs allSettled:Usa allSettled cuando necesites todos los resultados, y usa all cuando necesites fallar rápido.
  • async/await:En el código moderno se recomienda usar async/await, ya que su sintaxis es más concisa.

Mejores prácticas:Prioriza la sintaxis async/await; en esencia sigue basada en Promise, pero se escribe como código síncrono.


Resumen

Promise es el núcleo de la programación asíncrona en TypeScript.

  • Promise:Contenedor de operaciones asíncronas, con tres estados: pending/fulfilled/rejected.
  • then/catch:Procesa resultados asíncronos en cadena.
  • Promise.all:Espera a que todas se completen; si alguna falla, todo falla.
  • Promise.race:Devuelve el resultado que se complete primero.
  • Promise.allSettled:Espera a que todas terminen y devuelve el estado de cada una.

Recomendación:Usa la sintaxis async/await junto con Promise para que el código asíncrono sea seguro en tipos y fácil de leer.

x Otras extensiones