An overview of the

Promise is a unified solution for javascript asynchronous operations. It acts as a mediator between asynchronous operations and callback functions. Promise makes asynchronous operations more readable by allowing them to be written without nesting layer upon layer of callback functions.

The traditional callback function

Since the callback function is passed as an argument to another function, and the result of an asynchronous operation is usually the argument to that callback function, suppose I need to call F2 after f1, the traditional way to write it would be like this

function f1(fn){
	fn()
}
function f2(x){
	console.log(x)
}
f1(f2('hello')) //hello
Copy the code

But as soon as some tasks require multiple layers of nesting, the code is written

step1(function (value1) {
  step2(value1, function(value2) {
    step3(value2, function(value3) {
      step4(value3, function(value4) {
        // ...
      });
    });
  });
});
Copy the code

Promise is extremely clear, using then methods that return instance objects to make the code more readable

let promise =new Promise(step1)
promise.then(step2).then(step3)
Copy the code

Promise constructor

JS provides native writing to generate Promise instances

Let promise=new promise ((resolve,reject)=>{resolve()}else{reject()}})Copy the code

The Promise constructor takes one function as an argument, which in turn takes two functions as arguments, and executes resolve if the asynchronous operation succeeds, reject if it fails.

The instance state

Promise objects control asynchronous operations based on their state, and Promise instances have three states:

1. Asynchronous operation pending

2. Asynchronous operation will be successful (depressing)

3, Failed (Rejected)

There are only two transformation results of these three states:

  • Never finished to succeed
  • Never complete to fail

Once a state changes, it never changes again, and that’s where Promise comes from, meaning “Promise.”

Therefore, there are two results of Promise. If the Promise is successful, a value will be returned and the state will be changed to depressing

Error is raised and the status changes to Rejected

Resolve and reject functions

The resolve function changes the state of a Promise instance from “unfinished” to “successful” (i.e., from pending to depressing), is called when the asynchronous operation succeeds, and passes the result of the asynchronous operation as a parameter.

The Reject function changes the state of the Promise instance from “unfinished” to “failed” (i.e., from Pending to Rejected), calls it when the asynchronous operation fails, and passes the error reported by the asynchronous operation as an argument.

let a=new Promise((resolve,reject)=>{
	setTimeout(reject,1000)
})
Copy the code

After a second, reject is executed, at which point the state of instance object A changes

// a
[[PromiseState]]: "rejected"
[[PromiseResult]]: undefined
Copy the code

Use promise to encapsulate Ajax

function ajax(method, url, data) {
    const request = new XMLHttpRequest()
    return new promise((resolve, reject) => {
        request.open(method, url)
        request.onreadystatechange = () => {
            if (request.readyState === 4 && request.status === 200) {
                const obj = JSON.parse(request.response)
                resolve(obj)
            } else {
                reject(request.status)
            }
        }
        request.send(data)
    })
}
Copy the code

Promise.prototype.then()

The then method of the Promise instance, used to add the callback function.

The THEN method can accept two callback functions. The first is the callback function when the asynchronous operation succeeds (becomes the fulfilled state) and the second is the callback function when the asynchronous operation fails (becomes the fulfilled state) (this parameter can be omitted). Whenever the state changes, the corresponding callback function is called.

Var p=new Promise((resolve,reject)=>{resolve(' I succeed ')}) P.t hen ((data) = > {the console. The log (data)}, (data) = > {the console. The log (' failure '+ data)}) / / I'd succeededCopy the code

The above code returns a function that will execute the Promise directly, and continue to run the resolve function in the function, after which a Promise object will be returned to P, and then continue to call the callback function based on P. Because at this time, the state of P will be changed by the resolve function into depressing, So the first function after then is executed.

Chain operation of THEN

Each then is followed by a new Promise object, so the THEN can be chaining

p1
  .then(step1)
  .then(step2)
  .then(step3)
  .then(
    console.log,
    console.error
  );
Copy the code

In the code above, p1 is followed by four THEN, which means that there are four callback functions in sequence. As long as the state of the previous step becomes depressing, the callback functions that follow will be successively executed.

The last then method, the callbacks are console.log and console.error, with one important difference in usage. Console. log displays only the return value of step3, while console.error displays the error of any one of p1, step1, step2, or step3. For example, if the status of Step1 changes to Rejected, then step2 and Step3 won’t execute (because they are resolved callback functions). Promise starts looking, followed by the first callback function called Rejected, console.error in the code above. That is, the error of the Promise object is transitive.