TypeScript async/await Asynchronous Programming
async/await is syntactic sugar for asynchronous programming introduced in ES2017, making asynchronous code look like synchronous code.
SVG Diagram: async/await execution flowThe diagram above shows the advantages of async/await over traditional Promises: cleaner code and clearer execution flow.
Promise Basics
A Promise represents the eventual result of an asynchronous operation.
Example
// Create a Promise
var promise = new Promise(function(resolve, reject) {
var success = true;
if (success) {
resolve("Operation succeeded");
} else {
reject("Operation failed");
}
});
promise.then(function(result) {
console.log("Success: " + result);
})["catch"](function(error) {
console.log("Failure: " + error);
});
var promise = new Promise(function(resolve, reject) {
var success = true;
if (success) {
resolve("Operation succeeded");
} else {
reject("Operation failed");
}
});
promise.then(function(result) {
console.log("Success: " + result);
})["catch"](function(error) {
console.log("Failure: " + error);
});
Run result:
Success: Operation successful
async Functions
Use the async keyword to declare asynchronous functions.
Example
// async functions automatically return a Promise
async function greet(): Promise<string> {
return "Hello, World!";
}
greet().then(function(result) {
console.log("Result: " + result);
});
// Asynchronous function returns a Promise
async function getData() {
return { name: "Alice", age: 25 };
}
getData().then(function(data) {
console.log("Data: " + JSON.stringify(data));
});
async function greet(): Promise<string> {
return "Hello, World!";
}
greet().then(function(result) {
console.log("Result: " + result);
});
// Asynchronous function returns a Promise
async function getData() {
return { name: "Alice", age: 25 };
}
getData().then(function(data) {
console.log("Data: " + JSON.stringify(data));
});
Run result:
结果: Hello, World!
数据: {"name":"Alice","age":25}
await Keyword
await waits for a Promise to complete and obtains the result.
Example
// Simulate an asynchronous operation
function delay(ms: number): Promise<string> {
return new Promise(function(resolve) {
setTimeout(function() {
resolve("Done!");
}, ms);
});
}
async function main() {
console.log("Start...");
var result = await delay(100);
console.log("Result: " + result);
console.log("End");
}
main();
function delay(ms: number): Promise<string> {
return new Promise(function(resolve) {
setTimeout(function() {
resolve("Done!");
}, ms);
});
}
async function main() {
console.log("Start...");
var result = await delay(100);
console.log("Result: " + result);
console.log("End");
}
main();
Run result:
Start... Result: Complete! End
Error Handling
Use try/catch to handle asynchronous errors.
Example
function mayFail(shouldFail: boolean): Promise<string> {
return new Promise(function(resolve, reject) {
if (shouldFail) {
reject(new Error("Operation failed"));
} else {
resolve("Operation succeeded");
}
});
}
async function handleError() {
try {
var result = await mayFail(true);
console.log("Result: " + result);
} catch (error) {
console.log("Caught error: " + error.message);
}
}
handleError();
return new Promise(function(resolve, reject) {
if (shouldFail) {
reject(new Error("Operation failed"));
} else {
resolve("Operation succeeded");
}
});
}
async function handleError() {
try {
var result = await mayFail(true);
console.log("Result: " + result);
} catch (error) {
console.log("Caught error: " + error.message);
}
}
handleError();
Run result:
Error caught: Operation failed
Parallel Execution
Use Promise.all to execute multiple asynchronous operations in parallel.
Example
function fetchUser(id: number): Promise<{ id: number; name: string }> {
return Promise.resolve({ id: id, name: "User" + id });
}
async function main() {
// Execute sequentially
console.time("Serial");
var user1 = await fetchUser(1);
var user2 = await fetchUser(2);
console.log("Serial completed: " + user1.name + ", " + user2.name);
console.timeEnd("Serial");
// Execute in parallel
console.time("Parallel");
var results = await Promise.all([fetchUser(1), fetchUser(2)]);
console.log("Parallel completed: " + results[0].name + ", " + results[1].name);
console.timeEnd("Parallel");
}
main();
return Promise.resolve({ id: id, name: "User" + id });
}
async function main() {
// Execute sequentially
console.time("Serial");
var user1 = await fetchUser(1);
var user2 = await fetchUser(2);
console.log("Serial completed: " + user1.name + ", " + user2.name);
console.timeEnd("Serial");
// Execute in parallel
console.time("Parallel");
var results = await Promise.all([fetchUser(1), fetchUser(2)]);
console.log("Parallel completed: " + results[0].name + ", " + results[1].name);
console.timeEnd("Parallel");
}
main();
Run result:
串行完成: User1, User2 并行完成: User1, User2
Advantages of async/await over Promise
- Cleaner and more readable code
- Synchronous code style
- Better error stack
- Easy to debug
Summary
- async:Declaring async functions
- await:Awaiting a Promise
- Error handling:try/catch
- Parallel:Promise.all
Other extensions