A brief guide to Promises in JavaScript.
JavaScript developer

A brief guide to Promises in JavaScript.


A Promise in JavaScript is an object which returns a result after an asynchronous operation has finished. The result of a promise can either be a success or a failure.

You can think of it as similar to the real-life promise. We make a promise to do something in the future and we end up either fulfilling it or failing it.

The Promise has 3 states.

  • Pending – The Promise has no result yet.
  • Fulfilled – The Promise has resolved.
  • Rejected – The Promise has rejected.

Let’s see how to create a Promise.

let promise = new Promise((resolve, reject) => {
    const number = Math.round(Math.random() * 10);
    if(number <= 5) {
        resolve('Success');
    } else {
        reject(new Error('Failed'));
    }
});        

To create a Promise we use the Promise() constructor with the new keyword. The Promise() constructor accepts a callback function called “executer” which accepts two arguments i.e resolve and reject.

We need to call the resolve() function when the executer function obtains the result and call the reject() function when there is an error.

If you will console.log the Promise, you can check the Promise state.



(Promise in pending state)



(Promise in fulfilled state)



(Promise in rejected state)

Now to consume the Promise we use the Promise methods like then(), catch() and finally().


Promise.then() .


The then() method can accept two callback functions, first one executes when the Promise is resolved and the second one when Promise is rejected.

function getPromise(isTrue) {
    return new Promise((resolve, reject) => {
        if(isTrue) {
            resolve('Success');
        } else {
            reject(new Error('Failed'));
        }
    });
}

getPromise(true).then(
    response => console.log('Promise is resolved with result = ' + response),
    error => console.log('Promise is rejected with error = ' + error.message)
);
// Promise is resolved with result = Success

getPromise(false).then(
    response => console.log('Promise is resolved with result = ' + response),
    error => console.log('Promise is rejected with error = ' + error.message)
);
// Promise is rejected with error = Failed        

If we want to handle success and failure cases separately then we can use then() only for success and catch() for failure.


Promise.catch() .


The catch() method takes a callback function which executes when the Promise is rejected.

function getPromise(isTrue) {
    return new Promise((resolve, reject) => {
        if(isTrue) {
            resolve('Success');
        } else {
            reject(new Error('Failed'));
        }
    });
}

getPromise(false)
.then(response => console.log('Promise is resolved with result = ' + response))
.catch(error => console.log('Promise is rejected with error = ' + error.message))
// Promise is rejected with error = Failed        

If we are handling errors both in then() and catch(), then only the error handler inside then() executes in case of any error and not the handler inside catch().

let promise = new Promise((resolve, reject) => {
    reject(new Error('An error occurred'));
});

promise.then(null, () => console.log('Error caught inside then'))
.catch(() => console.log('Error caught inside catch'))
// Error caught inside then        

If further, any error occurred in the error handler of then(), then it will get caught in catch().

let promise = new Promise((resolve, reject) => {
    reject(new Error('Error occurred in Promise'));
});

promise.then(null, 
    err => {
        console.log('Error caught inside then, message: ' + err.message);
        throw new Error('Error occured in then');
    })
.catch(err => {
    console.log('Error caught inside catch, message: ' + err.message);
});

// Error caught inside then, message: Error occurred in Promise
// Error caught inside catch, message: Error occured in then        

Promise.finally() .


The finally() method takes a callback function which executes after the Promise is either resolved or rejected.

On Success

let promise = new Promise((resolve, reject) => {
    resolve('Success');
});

promise.then(res => console.log(res))
.catch(err => console.log(err.message))
.finally(() => console.log('Executing Finally'));
// Success
// Executing Finally        

On failure

let promise = new Promise((resolve, reject) => {
    reject(new Error('Failed'));
});

promise.then(res => console.log(res))
.catch(err => console.log(err.message))
.finally(() => console.log('Executing Finally'));
// Failed
// Executing Finally        

Promises Chaining .


We can execute a sequence of asynchronous operations one after the other by chaining methods then(), catch() and finally().

takeOrder()
.then(order => makeOrder(order))
.then(order => serveOrder(order))
.then(status => console.log(status))
.catch(err => console.log(err));        

Here takeOrder() will return a Promise that will be consumed in first then() method. The makeOrder() will return a Promise which will be consumed in the second then() method and serveOrder() will again return a Promise which will be consumed in third then() method. If any error occurred in any of the promises then it will get caught in catch() method.


Promise vs Callbacks .


Callbacks can be used to perform some action after an asynchronous operation finished. But if the nesting of callbacks increases it leads to callback hell and reduces readability. Promises are a better choice than callbacks when it comes to performing asynchronous operations.

Let’s take the order process example from the callback article and rewrite it using Promise in a simpler way.

function takeOrder() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const order = (Math.random() * 10) <= 5 ? 'Coffee' : 'Tea';
            resolve(order);
        }, 1000);
    })
}

function makeOrder(order) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(order);
        }, 1000);
    })
}

function serveOrder(order) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(order);
        }, 1000);
    })
}

takeOrder().then(order => {
    console.log('Order is for: ' + order);
    return makeOrder(order);
}).then(order => {
    console.log(order + ' is prepared');
    return serveOrder(order);
}).then(order => {
    console.log(order + ' is served');
});

// Order is for: Coffee
// Coffee is prepared
// Coffee is served        
Note: The value of order may differ as we are deciding order value using random number.

Promise.all() .


The Promise.all() method takes an iterable of promises as an input and returns a single Promise and it gets resolved when all the promises get resolved or any one of them gets rejected.

function getPromise(delay) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(delay + 100);
        }, delay);
    })
}

Promise.all([getPromise(1000), getPromise(3000), getPromise(2000)])
.then(responses => console.log(responses))
.catch(error => console.log(error));        

Promise.race() .


The Promise.race() method takes an iterable of promises and returns a single Promise which gets resolved/rejected as soon as any of the Promises resolved or rejected.

let promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('Promise 1');
    }, 1000);
});

let promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('Promise 2');
    }, 500);
});

Promise.race([promise1, promise2])
.then(res => console.log(res)) // Promise 2
.catch(err => console.log(err));        

?? Attention! ??


If you find any errors in the computer code or grammar, broken links while reading this article, please let me know. I apologize in advance for any inconvenience caused.



弗朗西斯安东尼奥斯

网页开发人员和设计师 | 构建可扩展的应用程序

1 周

I followed you #followback #followforfollow #followme #followbackalways #followbackteam #follow4follow #follow #teamfollowback #followalways #followall #follower #follows

回复

要查看或添加评论,请登录

Denis Rylikov的更多文章

社区洞察