Introduction to Promises
Promises are a fundamental concept in asynchronous programming in JavaScript and TypeScript. They represent a value that may be available now, or in the future, or never. Promises help manage asynchronous operations by providing a cleaner, more readable way to handle asynchronous code compared to traditional callback-based approaches.
Key Concepts
-
Promise States:
- Pending: Initial state, neither fulfilled nor rejected.
- Fulfilled: Operation completed successfully.
- Rejected: Operation failed.
-
Promise Methods:
- then(): Attaches callbacks for the resolution and/or rejection of the Promise.
- catch(): Attaches a callback for only the rejection of the Promise.
- finally(): Attaches a callback that is invoked when the Promise is settled (either fulfilled or rejected).
Creating a Promise
A Promise is created using the Promise
constructor, which takes a function (executor) with two parameters: resolve
and reject
.
const myPromise = new Promise<number>((resolve, reject) => { const success = true; // Simulate an operation if (success) { resolve(42); // Operation succeeded } else { reject('Operation failed'); // Operation failed } });
Using Promises
To handle the result of a Promise, you use the then
, catch
, and finally
methods.
myPromise .then((value) => { console.log('Success:', value); // Output: Success: 42 }) .catch((error) => { console.error('Error:', error); }) .finally(() => { console.log('Operation completed'); });
Practical Example
Let's create a function that simulates fetching data from an API using Promises.
function fetchData(url: string): Promise<string> { return new Promise<string>((resolve, reject) => { setTimeout(() => { const success = true; // Simulate a successful API call if (success) { resolve(`Data from ${url}`); } else { reject('Failed to fetch data'); } }, 2000); }); } fetchData('https://api.example.com/data') .then((data) => { console.log('Fetched data:', data); }) .catch((error) => { console.error('Error:', error); }) .finally(() => { console.log('Fetch operation completed'); });
Exercise
Create a function delayedMessage
that returns a Promise. The Promise should resolve with a message after a specified delay.
Task
- Create a function
delayedMessage
that takes two parameters:message
(string) anddelay
(number). - The function should return a Promise that resolves with the
message
after the specifieddelay
(in milliseconds).
Solution
function delayedMessage(message: string, delay: number): Promise<string> { return new Promise<string>((resolve) => { setTimeout(() => { resolve(message); }, delay); }); } // Usage delayedMessage('Hello, TypeScript!', 3000) .then((msg) => { console.log(msg); // Output after 3 seconds: Hello, TypeScript! });
Common Mistakes and Tips
- Forgetting to handle errors: Always use
catch
to handle potential errors in Promises. - Chaining Promises incorrectly: Ensure that each
then
returns a Promise if you are chaining multiple asynchronous operations. - Using
finally
for cleanup: Usefinally
to perform cleanup actions regardless of whether the Promise was fulfilled or rejected.
Conclusion
In this section, we covered the basics of Promises in TypeScript, including how to create and use them. We also provided a practical example and an exercise to reinforce the concepts. Understanding Promises is crucial for handling asynchronous operations effectively, and they form the foundation for more advanced asynchronous patterns like async/await
, which we will cover in the next topic.
TypeScript Course
Module 1: Introduction to TypeScript
- What is TypeScript?
- Setting Up the TypeScript Environment
- Basic Types
- Type Annotations
- Compiling TypeScript
Module 2: Working with Types
Module 3: Advanced Types
Module 4: Functions and Modules
Module 5: Asynchronous Programming
Module 6: Tooling and Best Practices
- Linting and Formatting
- Testing TypeScript Code
- TypeScript with Webpack
- TypeScript with React
- Best Practices