Detailed explanation of Promise in JS, elegant writing of asynchronous tasks

Hi I'm Shendi


Detailed explanation of Promise in JS, elegant writing of asynchronous tasks



Promise is a class provided by ECMAScript 6, a new addition to ES6, the purpose is to write complex asynchronous tasks more elegantly

Most browsers support it, some older browsers don't



Introduction

In the browser, the running of the program is synchronous (single-threaded). To achieve asynchrony, you can use the setTimeout function, and AJAX can also be executed asynchronously.

dad


When the requirements are very complicated, for example, to create an animation effect, move the element up by 50 pixels within two seconds, and then move to the left by 10 pixels within one second, the code is as follows

var ele = document.getElementById("id");
// 计算一次多少毫秒,两秒50,一秒10
var oneNum = 2000/50, twoNum = 1000/10;
var num = 0, num2 = 0;
// 两秒移动50像素
function animOne() {
    
    
    setTimeout(function () {
    
    
        ele.style.top -= 1;
        num++;
        if (num == oneNum) {
    
    
            animTwo();
        } else {
    
    
            anim();
        }
    }, oneNum);
}
// 一秒往左移动10像素
function animTwo() {
    
    
    setTimeout(function () {
    
    
        ele.style.left -= 1;
        num2++;
        if (num2 == twoNum) {
    
    
            // 动画完成
        } else {
    
    
            animTwo();
        }
    }, twoNum);
}
animOne();

The above code does not seem to be a big problem, but if the requirements change and move down on the previous basis, you need to call animThree (move down) after the execution of animTwo is completed. If the requirements change again, add more operations

Our solution is probably to change the form of directly specifying the function call after the operation is completed to pass the callback parameter call, for example

// 两秒移动50像素
function animOne(callback) {
    
    
    setTimeout(function () {
    
    
        ele.style.top -= 1;
        num++;
        if (num == oneNum) {
    
    
            if (callback) callback();
        } else {
    
    
            anim();
        }
    }, oneNum);
}
// 一秒往左移动10像素
function animTwo(callback) {
    
    
    setTimeout(function () {
    
    
        ele.style.left -= 1;
        num2++;
        if (num2 == twoNum) {
    
    
            if (callback) callback();
        } else {
    
    
            animTwo();
        }
    }, twoNum);
}
function animThree() {
    
    ...}
animOne(animTwo(animThree));

This method of asynchronous callback can be replaced by Promise, the purpose is to write complex asynchronous tasks more elegantly

can be understood as a norm




Advantage


more flexible

In the traditional callback, the callback function needs to be passed when calling, for example

animOne(aniTwo());

In Promise, it can be specified at any time (it can also be called after asynchronous execution is completed)



Support chain calls to solve callback hell

Callback hell refers to a situation where the nesting of callback methods is used excessively, making the code look very deep, difficult to maintain and understand. Here is an example:

function getDataFromServer(url, callback) {
    
    
  var httpRequest = new XMLHttpRequest();
  httpRequest.onreadystatechange = function() {
    
    
    if (httpRequest.readyState === 4 && httpRequest.status === 200) {
    
    
      var responseData = JSON.parse(httpRequest.responseText);
      callback(responseData);
    }
  };
  httpRequest.open('GET', url, true);
  httpRequest.send();
}

getDataFromServer('https://example.com/data1', function(response1) {
    
    
  getDataFromServer('https://example.com/data2/' + response1.id, function(response2) {
    
    
    getDataFromServer('https://example.com/data3/' + response2.id, function(response3) {
    
    
      // do something with the data
    });
  });
});

In the example above, the three nested callbacks can get very deep, making the code difficult to understand and maintain. To solve the callback hell problem, techniques such as Promise or async/await can be used.



Promise

Create an object through new Promise. The constructor has one parameter, which is a function. This function also has two parameters, usually named resolve and reject, which are also functions

Among them, when the function is successfully executed, resolve should be called, and reject should be called when the execution fails. You can define the parameters of these two functions by yourself

For example

var p = new Promise(function (resolve, reject) {
    
    
    if (true) {
    
    
        // 成功
        resolve("成功了");
    } else {
    
    
        // 失败
        reject("失败了");
    }
});

resolve and reject can be understood as callback functions

Promise itself is not asynchronous, but used to contain the execution of asynchronous operations

The function passed by creating a Promise will be executed directly (synchronously)



The Promise object has the following functions

name describe
then The function will be executed after success and return the promise object
catch Function, which will be executed after failure and returns promise object
finally Function, execute regardless of success or failure, return promise object

For example

p.then(function (val) {
    
    
    console.log(val);
}).catch(function (val) {
    
    
    console.log(val);
});


three states

The three states of Promise are:

  1. Pending (in progress): The Promise object is in the Pending state when it is created, indicating that the asynchronous operation is in progress and has not yet been completed.
  2. Fulfilled (completed): The asynchronous operation is successfully completed, the Promise object changes from the Pending state to the Fulfilled state, and a result value is returned at the same time.
  3. Rejected (failed): An error or exception occurs in the asynchronous operation, the Promise object changes from the Pending state to the Rejected state, and an error message is returned at the same time.

In the life cycle of Promise, the status will only change from Pending to Fulfilled or Rejected. Once the state transitions to Fulfilled or Rejected, it remains unchanged until the Promise object is released.



When the state changes to Fulfilled or Rejected, the corresponding callback function will be executed, and how many are executed, for example

p.then(function () {
    
    
   console.log(1);
}).then(function () {
    
    
   console.log(2);
}).then(function () {
    
    
   console.log(3);
});

Output 123 will be executed in sequence

If the catch chain is called, only the first one will be executed


Chain calls are executed in sequence, then can pass function parameters, and any exceptions in then will be directly executed catch

var p = new Promise(function (resolve, reject) {
    
    
    setTimeout(function () {
    
    
        console.log(1);
        resolve(2);
    }, 2000);
});
p.then(function (val) {
    
    
    console.log(val);
    return 3;
}).then(function (val) {
    
    
    console.log(val);
}).finally(function () {
    
    
    console.log("end");
}).then(function (val) {
    
    
    console.log(val);
    throw "4 error";
}).catch(function (val) {
    
    
    console.log(val);
});

insert image description here



async function

Async function is a specification of ECMAScript 2017 (ECMA-262) standard, which is supported by almost all browsers except Internet Explorer.

An asynchronous function is a type of JavaScript function that allows the execution of code not to block during execution, but to continue other operations in the background. Asynchronous functions typically use methods such as callbacks, Promises, or async/await to handle asynchronous operations.



Adding a modifier before the function asyncrepresents an asynchronous function, and the asynchronous function is executed asynchronously as a whole

In an asynchronous function, await can be used to wait for the promise result, for example

function showText(text, delay) {
    
    
    return new Promise(function (resolve, reject) {
    
    
        setTimeout(function () {
    
    
            console.log(text);
            resolve();
        }, delay);
    });
}
async function test() {
    
    
	await showText("一秒过去了", 1000);
   	await showText("两秒过去了", 1000);
    await showText("五秒过去了", 3000);
}
test();

The principle is exactly the same as the Promise native API mechanism, but it is easier for programmers to read

In the asynchronous function, you need to use try catch to catch the exception

If the promise has a normal return value, it can be assigned directly

async function test() {
    
    
    try {
    
    
        await new Promise(function (resolve, reject) {
    
    
            reject("错误");
            // 或者抛出错误
            // throw "错误";
        });
    } catch (e) {
    
     console.log(e); }
    
    await new Promise(function (resolve, reject) {
    
    
        resolve("返回值");
    });
}



END

Guess you like

Origin blog.csdn.net/qq_41806966/article/details/129721924