Front end interview: talk about your understanding of Promise in ES6 and use scenarios

Promise introduction

Promise asynchronous programming solution is more reasonable and powerful than the traditional solution (callback function), mainly to solve the problem of callback hell.

What is hell? Look at the following code:

doSomething(function(result) {
  doSomethingElse(result, function(newResult) {
    doThirdThing(newResult, function(finalResult) {
      console.log('Get the final result: ' + finalResult);
    }, failureCallback);
  }, failureCallback);
}, failureCallback);

Is it hard to read the above code? The above forms a classic callback hell.

Now rewrite the above code through Promise:

doSomething().then(function(result) {
  return doSomethingElse(result);
})
.then(function(newResult) {
  return doThirdThing(newResult);
})
.then(function(finalResult) {
  console.log('Get the final result: ' + finalResult);
})
.catch(failureCallback);

characteristic

  1. The state of the object is not affected by the outside world.
    Promise object represents an asynchronous operation and has three states:

    pending: in progress.
    Fully: completed successfully
    rejected: failed

    Only the result of asynchronous operation can determine the current state, and no other operation can change this state.

  2. Once the state changes, it will not change again. This result can be obtained at any time.
    There are only two possibilities for the state of the Promise object to change: from Pending to Resolved and from Pending to Rejected. As long as these two situations occur, the state will solidify, will not change again, and will always maintain this result. Even if the change has occurred, you will get this result immediately if you add a callback function to the Promise object. This is completely different from events. The characteristic of events is that if you miss it and listen again, you won't get results.

advantage

  • Chain operation reduces coding difficulty
  • Code readability is significantly enhanced

shortcoming

  • Promise cannot be cancelled. Once it is created, it will be executed immediately. It cannot be cancelled halfway.
  • If the callback function is not set, the error thrown by Promise will not be reflected to the outside.
  • When it is in Pending status, it is impossible to know which stage it has reached (just started or about to be completed).

Example method

(1) then is the callback function when the instance state changes. The first parameter is the callback function in the resolved state, and the second parameter is the callback function in the rejected state

(2) The then method returns a new promise instance, which is why promise can be chained

getJSON("/posts.json").then(function(json) {
  return json.post;
}).then(function(post) {
  // ...
});

(3)catch

The catch() method is then(null, rejection) or An alias for then(undefined, rejection), which specifies the callback function when an error occurs

getJSON('/posts.json').then(function(posts) {
  // ...
}).catch(function(error) {
  // Error occurred when processing getJSON and the previous callback function
  console.log('An error occurred!', error);
});

(4)finally()

The finally() method is used to specify the operation that will be performed regardless of the final state of the Promise object

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

Constructor method

(1)all
Promise. The all () method is used to wrap multiple promise instances into a new promise instance

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

Accept an array (iteration object) as a parameter. All array members should be Promise instances

The status of instance p is determined by p1, p2 and p3, which are divided into two types:

  • Only when the states of p1, p2 and p3 become fully, the state of p will become fully. At this time, the return values of p1, p2 and p3 form an array and are passed to the callback function of p
  • As long as one of p1, p2 and p3 is rejected, the status of p will become rejected. At this time, the return value of the first rejected instance will be passed to the callback function of p

Note that if the Promise instance as a parameter defines its own catch method, once it is rejected, it will not trigger Promise Catch method of all()

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

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

As long as one of p1, p2 and p3 takes the lead in changing the state, the state of p will change accordingly

The return value of the Promise instance changed first is passed to the callback function of p

(3)allSettled()
Promise. The allsettled () method takes a set of promise instances as parameters and wraps them into a new promise instance

The wrapper instance will not end until all of these parameter instances return results, whether fully or rejected

const promises = [
  fetch('/api-1'),
  fetch('/api-2'),
  fetch('/api-3'),
];

await Promise.allSettled(promises);
removeLoadingIndicator();

(4)resolve()
Convert existing objects to Promise objects

Promise.resolve('foo')
// Equivalent to
new Promise(resolve => resolve('foo'))

Parameters can be divided into four cases as follows:

  • The parameter is a Promise instance, Promise Resolve will return the instance intact without any modification
  • The parameter is a thenable object, Promise Resolve turns the object into a Promise object, and then immediately executes the then() method of the thenable object
  • The parameter is not an object with a then() method, or it is not an object at all, Promise Resolve () returns a new Promise object with the status resolved
  • When there are no parameters, a Promise object in resolved state is returned directly

(5)reject()
Promise. The reject (reason) method will also return a new promise instance with the status of rejected

const p = Promise.reject('Error ');
// Equivalent to
const p = new Promise((resolve, reject) => reject('Error '))

p.then(null, function (s) {
  console.log(s)
});
// Error 

Usage scenario

Write the picture loading as a Promise. Once the loading is completed, the Promise state will change

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

Through chain operation, multiple rendering data are given to then to perform their respective duties. Or when the next asynchronous request depends on the result of the previous request, we can also solve the problem friendly through chain operation

// attend to each one 's own duties
getInfo().then(res=>{
    let { bannerList } = res
    //Rendering a carousel
    console.log(bannerList)
    return res
}).then(res=>{
    
    let { storeList } = res
    //Render store list
    console.log(storeList)
    return res
}).then(res=>{
    let { categoryList } = res
    console.log(categoryList)
    //Render classification list
    return res
})

Multiple requests are merged through all() to summarize all the request results. You only need to set one loading

function initLoad(){
    // loading.show() / / loading
    Promise.all([getBannerList(),getStoreList(),getCategoryList()]).then(res=>{
        console.log(res)
        loading.hide() //Close loading
    }).catch(err=>{
        console.log(err)
        loading.hide()//Close loading
    })
}
//Data initialization    
initLoad()

Through race, you can set the timeout of picture request

//Request a picture resource
function requestImg(){
    var p = new Promise(function(resolve, reject){
        var img = new Image();
        img.onload = function(){
           resolve(img);
        }
        //img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg "; correct
        img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg1";
    });
    return p;
}

//A delay function used to time requests
function timeout(){
    var p = new Promise(function(resolve, reject){
        setTimeout(function(){
            reject('Picture request timeout');
        }, 5000);
    });
    return p;
}

Promise
.race([requestImg(), timeout()])
.then(function(results){
    console.log(results);
})
.catch(function(reason){
    console.log(reason);
});

Keywords: Javascript Promise

Added by brodwilkinson on Sun, 16 Jan 2022 21:14:05 +0200