TypeScript Promise In-Depth
Promise is the foundation of JavaScript asynchronous programming, and TypeScript has full type support for Promise.
Through generic parameters, you can precisely specify the types of the Promise's resolved value and rejected value.
SVG Diagram: Promise Workflow
Why Promise?
In JavaScript, many operations are asynchronous, such as network requests, file reading, timers, etc.
Promise provides a unified asynchronous programming interface, making asynchronous code easier to write and manage.
TypeScript's generic support ensures the type safety of Promise.
Concept description:A Promise is an object that represents the final result of an asynchronous operation. It has three states: pending (in progress), fulfilled (succeeded), rejected (failed).
Creating a Promise
Use the Promise constructor to create a Promise, passing in an executor function.
Example
// Promise<string> means a string is returned on success
var promise = new Promise<string>(function(resolve, reject) {
var success = true;
if (success) {
// Calling resolve means the operation succeeded; pass in the result value
resolve("Success!");
} else {
// Calling reject means the operation failed; pass in the error
reject(new Error("Failure"));
}
});
// Use then to handle the success case
promise.then(function(value) {
console.log("Done: " + value);
})["catch"](function(error) {
// Use catch to handle the failure case
console.log("Error: " + error.message);
});
Output:
Complete: Success!
Generics explanation:
Promise<T>The T in Promise<T> is the type of the value when the Promise resolves successfully. This allows TypeScript to infer the type of the returned value.
Promise Chaining
The then and catch methods return a new Promise, allowing chained calls.
Example
var promise = Promise.resolve(1)
.then(function(n) {
// First then, n = 1
return n * 2; // Returns 2
})
.then(function(n) {
// Second then, n = 2
return n + 10; // Returns 12
})
.then(function(n) {
// Third then, n = 12
console.log("Final result: " + n);
return n;
});
console.log("Promise chain: " + promise);
Output:
最终结果: 12 Promise 链: [object Promise]
Chaining:Each then returns a new Promise, allowing us to execute multiple asynchronous operations in sequence.
Promise.all
Promise.all waits for all Promises to complete and returns an array containing all results.
Example
var p1 = Promise.resolve(1);
var p2 = Promise.resolve(2);
var p3 = Promise.resolve(3);
// Promise.all waits for all Promises to complete
// Returns an array containing the results of all Promises
Promise.all([p1, p2, p3]).then(function(results) {
console.log("All completed: " + results);
// Calculate the sum
console.log("Sum: " + results.reduce(function(a, b) { return a + b; }, 0));
});
Output:
全部完成: 1,2,3 总和: 6
Note:If any Promise fails, Promise.all will immediately reject and will not wait for other Promises to complete.
Promise.race
Promise.race returns the result of the Promise that completes first (whether successful or failed).
Example
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 returns the result of the first Promise to complete
Promise.race([p1, p2, p3]).then(function(value) {
console.log("First to complete: " + value);
});
Output:
最先完成: p3
Use cases:Promise.race is often used to implement timeout functionality: racing a long-running Promise against a timeout Promise.
Promise.allSettled
Promise.allSettled waits for all Promises to settle (whether successful or failed) and returns the status and result of each Promise.
Example
var p1 = Promise.resolve("Success");
var p2 = Promise.reject(new Error("Failure"));
var p3 = Promise.resolve("Done");
// Promise.allSettled waits for all Promises to settle
// Returns the status and value/reason of each 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);
}
});
});
Output:
Promise 0: 成功 Promise 1: 失败 Promise 2: 完成
Differences:Promise.all stops immediately on the first failure; Promise.allSettled waits for all Promises to settle.
Promise Type Annotations
TypeScript's generic support makes Promise type declarations precise.
Example
// Promise<{ name: string; age: number }> specifies the type of the returned user object
function getUser(): Promise<{ name: string; age: number }> {
return Promise.resolve({ name: "Alice", age: 25 });
}
// async function: implicitly returns a Promise
async function main() {
// await automatically infers the type of user
var user = await getUser();
console.log("User: " + JSON.stringify(user));
}
main();
Type inference:TypeScript automatically infers the return type of a Promise based on generic parameters, giving us full type hints in async/await as well.
Notes
- Generic parameters:Always specify generic parameters for Promise to clarify the return type
- Error handling:Remember to use catch to handle Promise failures
- all vs allSettled:Use allSettled when you need all results, and use all when you need fast failure.
- async/await:Modern code recommends using async/await, as the syntax is more concise
Best practices:Prefer async/await syntax; it is still based on Promise, but reads like synchronous code.
Summary
Promise is the core of TypeScript asynchronous programming.
- Promise:An asynchronous operation container with three states: pending/fulfilled/rejected
- then/catch:Chaining to handle asynchronous results
- Promise.all:Waits for all to complete; fails entirely if any one fails
- Promise.race:Returns the first completed result
- Promise.allSettled:Waits for all to settle and returns the status of each
x Other extensionsRecommendation:Use async/await syntax with Promise to make asynchronous code both type-safe and easy to read.