Promise TypeScript en profondeur
Promise est la base de la programmation asynchrone en JavaScript, et TypeScript offre une prise en charge complète des types pour Promise.
Grâce aux paramètres génériques, vous pouvez spécifier précisément les types de la valeur résolue et de la valeur rejetée d'une Promise.
Diagramme SVG : flux de travail d'une Promise
Pourquoi Promise ?
En JavaScript, de nombreuses opérations sont asynchrones, telles que les requêtes réseau, la lecture de fichiers, les minuteurs, etc.
Promise fournit une interface de programmation asynchrone unifiée, ce qui rend le code asynchrone plus facile à écrire et à gérer.
La prise en charge des génériques de TypeScript garantit la sécurité des types de Promise.
Description du concept :Une Promise est un objet qui représente le résultat final d'une opération asynchrone. Elle a trois états : pending (en cours), fulfilled (réussi), rejected (échoué).
Création d'une Promise
Utilisez le constructeur Promise pour créer une Promise, en passant une fonction exécutrice.
Exemple
// Promise<string> signifie qu'une chaîne est renvoyée en cas de succès
var promise = new Promise<string>(function(resolve, reject) {
var success = true;
if (success) {
// Appeler resolve signifie que l'opération a réussi ; transmettez la valeur du résultat
resolve("Succès !");
} else {
// Appeler reject signifie que l'opération a échoué ; transmettez l'erreur
reject(new Error("Échec"));
}
});
// Utilisez then pour gérer le cas de succès
promise.then(function(value) {
console.log("Terminé : " + value);
})["catch"](function(error) {
// Utilisez catch pour gérer le cas d'échec
console.log("Erreur : " + error.message);
});
Sortie :
Complete: Success!
Explication des génériques :
Promise<T>Le T dans Promise<T> est le type de la valeur lorsque la Promise se résout avec succès. Cela permet à TypeScript d'inférer le type de la valeur retournée.
Chaînage de promesses
Les méthodes then et catch retournent une nouvelle Promise, ce qui permet des appels en chaîne.
Exemple
var promise = Promise.resolve(1)
.then(function(n) {
// Premier then, n = 1
return n * 2; // Renvoie 2
})
.then(function(n) {
// Deuxième then, n = 2
return n + 10; // Renvoie 12
})
.then(function(n) {
// Troisième then, n = 12
console.log("Résultat final : " + n);
return n;
});
console.log("Chaîne de promesses : " + promise);
Sortie :
最终结果: 12 Promise 链: [object Promise]
Chaînage :Chaque then renvoie une nouvelle Promise, ce qui nous permet d'exécuter plusieurs opérations asynchrones en séquence.
Promise.all
Promise.all attend que toutes les promesses soient terminées et renvoie un tableau contenant tous les résultats.
Exemple
var p1 = Promise.resolve(1);
var p2 = Promise.resolve(2);
var p3 = Promise.resolve(3);
// Promise.all attend que toutes les promesses soient terminées
// Renvoie un tableau contenant les résultats de toutes les promesses
Promise.all([p1, p2, p3]).then(function(results) {
console.log("Tout est terminé : " + results);
// Calculer la somme
console.log("Somme : " + results.reduce(function(a, b) { return a + b; }, 0));
});
Sortie :
全部完成: 1,2,3 总和: 6
Remarque :Si une Promise échoue, Promise.all rejettera immédiatement et n'attendra pas que les autres Promises se terminent.
Promise.race
Promise.race renvoie le résultat de la Promise qui se termine en premier (qu'elle réussisse ou échoue).
Exemple
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 renvoie le résultat de la première Promise à se terminer
Promise.race([p1, p2, p3]).then(function(value) {
console.log("Premier à se terminer : " + value);
});
Sortie :
最先完成: p3
Cas d'utilisation :Promise.race est souvent utilisé pour implémenter une fonctionnalité de délai d'attente : faire concourir une Promise de longue durée avec une Promise de délai d'attente.
Promise.allSettled
Promise.allSettled attend que toutes les Promises soient réglées (qu'elles réussissent ou échouent) et renvoie le statut et le résultat de chaque Promise.
Exemple
var p1 = Promise.resolve("Success");
var p2 = Promise.reject(new Error("Failure"));
var p3 = Promise.resolve("Done");
// Promise.allSettled attend que toutes les Promesses soient réglées
// Renvoie le statut et la valeur/raison de chaque Promesse
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);
}
});
});
Sortie :
Promise 0: 成功 Promise 1: 失败 Promise 2: 完成
Différences :Promise.all s'arrête immédiatement au premier échec ; Promise.allSettled attend que toutes les Promesses soient réglées.
Annotations de type Promise
La prise en charge des génériques de TypeScript rend les déclarations de type Promise précises.
Exemple
// Promise<{ name: string; age: number }> spécifie le type de l'objet user retourné
function getUser(): Promise<{ name: string; age: number }> {
return Promise.resolve({ name: "Alice", age: 25 });
}
// fonction async : renvoie implicitement une Promise
async function main() {
// await déduit automatiquement le type de user
var user = await getUser();
console.log("Utilisateur : " + JSON.stringify(user));
}
main();
Inférence de type :TypeScript déduit automatiquement le type de retour d'une Promise en fonction du générique, ce qui nous donne également des indications de type complètes dans async/await.
Notes
- Paramètres génériques :Spécifiez toujours les paramètres génériques pour Promise afin de clarifier le type de retour
- Gestion des erreurs :N'oubliez pas d'utiliser catch pour gérer les échecs de Promise
- all vs allSettled :Utilisez allSettled lorsque vous avez besoin de tous les résultats, et utilisez all lorsque vous avez besoin d'un échec rapide.
- async/await :Le code moderne recommande d'utiliser async/await, car la syntaxe est plus concise
Bonnes pratiques :Privilégiez la syntaxe async/await ; elle est toujours basée sur Promise, mais se lit comme du code synchrone.
Résumé
Promise est au cœur de la programmation asynchrone en TypeScript.
- Promise :Un conteneur d'opérations asynchrones avec trois états : pending/fulfilled/rejected
- then/catch :Chaînage pour gérer les résultats asynchrones
- Promise.all :Attend que tout soit terminé ; échoue entièrement si l'une d'elles échoue
- Promise.race :Renvoie le premier résultat terminé
- Promise.allSettled :Attend que toutes soient réglées et renvoie le statut de chacune
x Autres extensionsRecommandation :Utilisez la syntaxe async/await avec Promise pour rendre le code asynchrone à la fois sûr au niveau des types et facile à lire.