DEV Community

Luis A.
Luis A.

Posted on

JavaScript Promises: Making Sense of the Madness ๐Ÿ˜ค

Hey there, party people! ๐ŸŽ‰ If you've ever found yourself scratching your head over Promises in JavaScript, you're in the right place. I've been seeing a ton of questions about this topic, so today I'm on a mission to clear things up and help you master the art of Promises. Get ready for some fun, laughter, and a little bit of learning as we venture into the wild world of Promises! ๐Ÿ˜Ž ๐ŸŽข

Whatโ€™s a Promise in JavaScript? ๐Ÿค”

A Promise is a JavaScript object that represents an asynchronous function. It's like your friend telling you they'll buy you a pizza later. You don't know exactly when it's gonna happen, but you trust them to deliver. ๐Ÿ•

// Create a Promise object
let sayHello = new Promise(function (resolve, reject) {

    // In 5 seconds, resolve the Promise.
    // Pass along "Hi, universe!" to any callback methods
    setTimeout(function () {
        resolve('Hi, universe!');
    }, 5000);

});
Enter fullscreen mode Exit fullscreen mode

In the example above, sayHello() is a Promise that in 5 seconds, something will happen. You can attach functions that should run when the Promise resolves using the Promise.then() method.

// After 5 seconds, if the Promise resolves,
// this will log "Hi, universe!" into the console
sayHello.then(function (msg) {
    console.log(msg);
});
Enter fullscreen mode Exit fullscreen mode

When you create a Promise, you pass in a callback function as an argument.

Inside the function, you define two parameters: resolve and reject. These are implicit arguments the Promise passes into your callback function.

When the Promise should be considered completed, run the resolve() method. You can pass in arguments that should get passed into the Promise.then() method callback function into the resolve() method.

In the example above, we passed Hi, universe! into resolve(). This was passed along to the Promise.then() method as the msg argument.

Rejecting a Promise ๐Ÿšซ

Similarly, you run the reject() method if the Promise should be considered failed. This is like your friend promising you that pizza, but then they run out of money. Bummer, dude! ๐Ÿ˜ข

You can pass in any error messages or information about the rejection as arguments. You can run a callback when a Promise fails using the Promise.catch() method.

In the next example, letโ€™s modify sayHello() to reject() before the timeout completes.

// Create a Promise object
let sayHello = new Promise(function (resolve, reject) {

    reject('Unable to say hi.');

    // In 5 seconds, resolve the Promise.
    // Pass along "Hi, universe!" to any callback methods
    setTimeout(function () {
        resolve('Hi, universe!');
    }, 5000);

});
Enter fullscreen mode Exit fullscreen mode

Now, we can add a Promise.catch() method to detect this failure and do something about it. (Like ordering our own pizza! ๐Ÿ•)

// Will warn "Unable to say hi." in the console.
sayHello.then(function (msg) {
    console.log(msg);
}).catch(function (error) {
console.warn(error);
});
Enter fullscreen mode Exit fullscreen mode

Because reject() runs before resolve() does, the catch() callback method will run and show the error message that was passed in.

Chaining ๐Ÿš‚

You can chain multiple Promise.then() methods together, and theyโ€™ll run in sequence. It's like setting up a domino effectโ€”each one triggers the next. ๐ŸŽฒ

Whatever you return from the current Promise.then() method gets passed along to the next Promise.then() method after it in the chain. Letโ€™s create a new Promise called count.

It will resolve() immediately, and pass along 1 as an argument.

// Create a Promise object
let count = new Promise(function (resolve, reject) {
    resolve(1);
});
Enter fullscreen mode Exit fullscreen mode

Now, we can chain some Promise.then() methods together. In each one one, weโ€™ll log num, increase it by 1, and return it to the next argument in the sequence.

In the first Promise.then() method, num is 1. In the second, itโ€™s 2. In the last one, itโ€™s 3.


// logs 1, then 2, then 3, to the console
count.then(function (num) {
    console.log(num);
    return num + 1;
}).then(function (num) {
    console.log(num);
    return num + 1;
}).then(function (num) {
    console.log(num);
    return num + 1;
});
Enter fullscreen mode Exit fullscreen mode

You can attach Promise.then() methods at any time โฐ

One of my favorite things about Promises is that if you assign one to a variable, you can attach Promise.then() methods on it at any timeโ€”even after the Promise has already resolved.

If the Promise hasnโ€™t resolved yet, the callback will run once it does. If it has resolved, the callback will run immediately. It's like a pizza that's already been delivered and is just waiting for you to dig in. ๐Ÿ•

// Create a Promise that resolves immediately
let question = new Promise(function (resolve, reject) {
    resolve(42);
});

// Attach a callback 5 seconds after it's resolved
setTimeout(function () {

    // This will run as soon as the timeout completes, because the Promise has already resolved
    question.then(function (answer) {
        console.log(answer);
    });

}, 5000);
Enter fullscreen mode Exit fullscreen mode

Hope that helps a bit, folks! Tomorrow, weโ€™ll look at a practical use of Promises: the fetch() method. Stay tuned, and don't forget to practice those Promises in the meantime. After all, practice makes perfect...or at least a little less confusing! ๐Ÿ˜„

Top comments (0)