Front-end JavaScript Promise

Front-end JavaScript Promise

1. What is Promise

Promise is a solution for asynchronous programming. ES6 already provides native Promise objects. A Promise object can be in the following states ( fulfilled and rejected states will not change once confirmed):

  • pending : The initial state, which is neither redeemed nor rejected.
  • fulfilled : means the operation completed successfully.
  • rejected : means the operation failed.

2. Basic usage

The Promise object is a constructor used to create Promise instance. It receives two parameters: resolve and reject .

  • The function of resolve is to change the state of Promise object from pending to fulfilled . It is called when the asynchronous operation succeeds and passes the result of the asynchronous operation as a parameter.
  • The function of reject is to change the state of Promise object from pending rejected . It is called when the asynchronous operation fails, and the error reported by the asynchronous operation is passed as a parameter.
const promise = new Promise(function(resolve, reject) {
  // ... 
  if (/* asynchronous operation successful*/){
    resolve(value);
  } else {
    reject(error);
  }
});


After Promise instance is generated, use the then method to specify the callback functions for fulfilled state and rejected state respectively.

  • then receives two parameters, the first is the callback function when the state of Promise object becomes fulfilled , and the second is the callback function when the state becomes rejected .
  • catch receives the callback function when the state of Promise object becomes rejected .
promise.then(function (value){
 // ....
},function (err){
 // .... err
})
  
promise.then(function (value){
 // ....
}).catch(function (err){
    // ....
})

3. Promise Methods

3.1 Promise.prototype.then()

The then method is defined on the prototype object Promise.prototype . As mentioned earlier, it accepts two optional parameters. The first parameter is the callback function of fulfilled state, and the second parameter is the callback function of rejected state.

The then method returns a new Promise instance, which makes it convenient for us to use chain writing. For example, if you write then " after "then", when the first callback function is completed, the return result will be passed as a parameter to the second callback function. This chaining approach makes it easy to specify a set of callback functions to be called in sequence.

loadData().then(function (value){
    return 3
}).then(function (num){
    console.log("ok", num) // 3
})

3.2 Promise.prototype.catch()

The catch method is used to specify a callback function when an error occurs. If an asynchronous operation throws an error, the state changes to rejected , and the callback function specified by catch() method is called to handle the error.

const promise = new Promise(function(resolve, reject) {
  throw new Error('unkonw error'); // throw error state changes to -> reject
});
const promise = new Promise(function(resolve, reject) {
  reject('unkonw error') // Use the reject() method to change the state to -> reject
});
promise.catch(function(error) {
  console.log(error);
});


The error of Promise object will be propagated backwards until it is caught. For example, the following code: catch will capture the errors thrown in loadData and the two thens.

loadData().then(function(value) {
  return loadData(value);
}).then(function(users) {
 
}).catch(function(err) {
  // Handle errors from the first three Promises });


If we don't set catch() , Promise will not throw the error out when an error occurs, which means it will not affect the execution of external code.

const promise = new Promise(function(resolve, reject) {
   resolve(a) // ReferenceError: a is not defined
});
promise.then(function(value) {
  console.log('value is ', value)
});
setTimeout(() => { console.log('code is run') }, 1000); // code is run

3.3 Promise.prototype.finally()

finally() method performs operations regardless of the final state of Promise object. Below is a general structure where we use Promise.

promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});

3.4 Promise.all()

Promise.all() method can wrap multiple Promise instances into a new Promise instance and return it.

const promise = Promise.all([p1, p2, p3]);


The new promise state depends on the "incoming promise ".

  • Only when all "incoming promise " have become fulfilled will its status become fulfilled . At this time, the return values ​​of the "incoming promise " form an array and are passed to the callback function of promise .
  • If one of the "incoming promises" is rejected, the state of the new promise will become rejected , and the return value of the first reject promise will be passed to promise callback function.
const promises = [1,2,3,4].map(function (id) {
  return loadData(id);
});

Promise.all(promises).then(function (users) {
  // ...
}).catch(function(err){
  // ...
});

3.5 Promise.race()

Promise.race() method also wraps multiple Promise instances into a new Promise instance.

The parameters of Promise.race() method are the same as those of Promise.all() method.

const promise = Promise.race([p1, p2, p3]);


Promise.all() vs. Promise.race () :

Promise.all() returns all successful promise values ​​if all are executed successfully, and returns the first failed value if any fail.
Promise.race() returns the first promise value that is completed, which may be fulfilled or rejected .
The usage scenarios of these two methods .

Scenario 1: After a user logs in to the homepage of a social networking site, they will asynchronously request to pull user information, follow list, and fan list. We need to ensure that all data requests are successful before rendering the page. If any data fails, the page will be redirected. Here we can use Promise.all .

function initUserHome() {
  Promise.all([
  new Promise(getMe),
  new Promise(getFollows),
  new Promise(getFans)
])  
    .then(function(data){
     // Display the page })
    .catch(function(err){
    // .... redirect page });
};

initUserHome();

Scenario 2: If we are making a ticket grabbing software, although we request many ticket selling channels, we only need to return the first completed Promise each time. Here we can use Promise.race .

function getTicket() {
  Promise.race([
  new Promise(postASell),
  new Promise(postBSell),
  new Promise(postCSell)
])  
    .then(function(data){
     // Ticket grab success})
    .catch(function(err){
    // .... failed to grab the ticket, try again});
};

getTicket();

3.6 Promise.allSettled()

When using Promise.all() , if one Promise fails, the other Promises will not stop executing.

const requests = [
  fetch('/url1'),
  fetch('/url2'),
  fetch('/url3'),
];

try {
  await Promise.all(requests);
  console.log('All requests were successful.');
} catch {
  console.log('One request failed, other requests may not have finished yet.');
}

Sometimes, we want to wait until a group of asynchronous operations are completed before proceeding to the next step. At this time, you need to use Promise.allSettled() , whose parameter is an array, each member of the array is a Promise object, and returns a new Promise object. It only waits until all the Promise objects in the parameter array have changed their status (whether fulfilled or rejected ), and the returned Promise object will change its status.

const requests = [
  fetch('/url1'),
  fetch('/url2'),
  fetch('/url3'),
];

await Promise.allSettled(requests);
console.log('Execute after all requests are completed (including success and failure)');

3.7 Promise.any()

As long as one of the incoming Promise becomes fulfilled , the new Promise will become fulfilled ; if all the incoming Promise become rejected , the new Promise will become rejected.

Promise.any() is similar to Promise.race() , but the difference is that Promise.any() will not end because a certain Promise becomes rejected . It must wait until all parameter Promise become rejected .

Back to the scenario of multi-channel ticket grabbing using mise.race() , if we need to ensure that either one channel succeeds in grabbing tickets or all channels fail, it would be more appropriate to use Promise.any() .

function getTicket() {
  Promise.any([
  new Promise(postASell),
  new Promise(postBSell),
  new Promise(postCSell)
])  
    .then(function(data){
     // One ticket was successfully grabbed})
    .catch(function(err){
    // .... all channels failed });
};

getTicket();

3.8 Promise.resolve()

Promise.resolve() method converts an existing object into a Promise object. is equivalent to the following code:

new Promise(resolve => resolve(1))


The parameters passed in are different.

  • The parameter Promise instance will be returned unchanged without any modification.
  • The parameter is a thenable object, which will convert this object into a Promise object, and then immediately execute the then() method of the thenable object.
let thenable = {
  then: function(resolve, reject) {
    resolve(1);
  }
};


  • The parameter is a normal value, and a new Promise object is returned with a resolved status.
const promise = Promise.resolve(1);

promise.then(function (value) {
  console.log(value) // 1
});

  • No parameters, directly returns a Promise object in resolved state.

3.9 Promise.reject()

The Promise.reject(reason) method also returns a new Promise instance with a rejected status.

const promise = Promise.reject('unkonw error');
// equivalent to const promise = new Promise((resolve, reject) => reject('unkonw error'))

promise.then(null, function (s) {
  console.log(s)
});
//unknown error

4. Simple scene

Load images asynchronously:

function loadImageAsync(url) {
  return new Promise(function(resolve, reject) {
   const image = new Image();
    image.onload = resolve;
    image.onerror = reject;
    image.src = url;
  });
}

Request timeout processing:

//Request function request(){
    return new Promise(function(resolve, reject){
       // code ....
         resolve('request ok')
    })
}

function timeoutHandle(time){
   return new Promise(function(resolve, reject){
        setTimeout(function(){
            reject('timeout');
        }, time);
    });
}

Promise.race([
    request(),
    timeoutHandle(5000)
])
.then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err) // timeout
})

This is the end of this article about front-end JavaScript Promise . For more relevant JavaScript Promise content, please search 123WORDPRESS.COM’s previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • A Deep Dive into JavaScript Promises
  • Detailed explanation of Promises in JavaScript
  • JS 9 Promise Interview Questions
  • How to add abort function to promise in JS
  • Thoroughly understand JavaScript's Promise

<<:  A brief discussion on the characteristics of CSS float

>>:  HTML form tag tutorial (5): text field tag

Blog    

Recommend

Detailed explanation of Json format

Table of contents A JSON is built on two structur...

How to configure tomcat server for eclipse and IDEA

tomcat server configuration When everyone is lear...

Detailed explanation of how to use Vue self-nested tree components

This article shares with you how to use the Vue s...

Detailed explanation of anonymous slots and named slots in Vue

Table of contents 1. Anonymous slots 2. Named slo...

Several ways to set the expiration time of localStorage

Table of contents Problem Description 1. Basic so...

React gets input value and submits 2 methods examples

Method 1: Use the target event attribute of the E...

10 reasons why Linux is becoming more and more popular

Linux has been loved by more and more users. Why ...

Mysql auto-increment primary key id is not processed in this way

Mysql auto-increment primary key id does not incr...

Grid systems in web design

Formation of the grid system In 1692, the newly c...

About uniApp editor WeChat sliding problem

The uniapp applet will have a similar drop-down p...

Let's talk about Vue's mixin and inheritance in detail

Table of contents Preface Mixin Mixin Note (dupli...

Problems with index and FROM_UNIXTIME in mysql

Zero, Background I received a lot of alerts this ...

jQuery plugin to achieve image suspension

This article shares the specific code of the jQue...

Detailed explanation of nodejs built-in modules

Table of contents Overview 1. Path module 2. Unti...

Solution to the problem that docker nginx cannot be accessed after running

## 1 I'm learning docker deployment recently,...