In this lesson, you will learn how to create "Deferred" objects, which allow you to manually trigger the resolution of a promise from anywhere in your code, rather than being trapped inside a standard executor function.
The "Deferred" Pattern
Usually, when you create a promise, you pass an "executor" function: new Promise((resolve, reject) => { ... }). The logic must live inside that block. But what if you want to hold onto a promise and resolve it later, in a completely different part of your application?
A Deferred object is a simple container that holds the resolve and reject functions as properties, exposing them to the outside world.
Implementing a Deferred Object
You can implement this pattern by creating a class that wraps a promise and extracts its handlers:
class Deferred {
constructor() {
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
}
}
// Usage
const pendingTask = new Deferred();
// We can pass the promise to a consumer
pendingTask.promise.then(data => console.log("Received:", data));
// Elsewhere in the app, we decide when to resolve it
setTimeout(() => {
pendingTask.resolve("Operation complete!");
}, 2000);
Why use this?
This pattern is incredibly useful for event-based systems. For example, if you are writing a custom server module, you might want to return a promise to a client that waits for a specific network event to occur. Instead of wrapping the entire event listener setup in a new Promise constructor, you can instantiate a Deferred object, store it, and call .resolve() whenever that specific network packet finally arrives.
It decouples the creation of the promise from the event that completes it, giving you total control over the flow of your asynchronous operations. By manually holding onto those resolver functions, you turn an opaque process into a controllable, predictable object.
Key Takeaway: A Deferred object allows you to bridge the gap between event-driven triggers and promise-based flow control by exposing the resolve and reject hooks as accessible properties.