What is the Promise?

  • Promise is a new solution for asynchronous programming in JS. (The old solution was to simply use callbacks.)
  • Syntactically, a PROMISE is a constructor.
  • Functionally, a Promise object is used to encapsulate an asynchronous operation and to return a success or failure value.
  • JS in the common asynchronous operation: timer, AJAX is generally asynchronous operation (can also be synchronous), callback functions can be understood as asynchronous (not rigorous asynchronous operation)… , and the rest is processed synchronously.

2. Why use Promise:

  • Promises are more flexible with callbacks. The old callback function must be specified before starting the asynchronous task.
  • Promise: Start an asynchronous task => Return a Promise object => Bind a callback function to the Promise object (you can even specify more than one after the asynchronous task ends)
  • Promise supports chained calls, which can solve the callback hell problem. (Callback hell is a nesting of multiple callback functions, called nesting dolls, which makes reading and exception handling difficult.)

3. First experience:

Effect: Clicking a button has a 30% chance of winning. Implementation: click the button to get a random number between 1 and 100, less than or equal to 30 output to win, otherwise the output is not in. During the simulation of asynchronous operation with the timer, the execution of judgment in the timer. (1) Basic writing method:

<button id="btn">click</button>

    <script>
        var btn = document.querySelector("#btn");
    // This function returns a random integer between two numbers, including both numbers
    function getRandomIntInclusive(min, max) {
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min + 1)) + min; // Contain maximum value, contain minimum value
    }
    // Click the event
     btn.addEventListener('click'.function(){
         // 1 second timer to simulate asynchronous operation
         setTimeout(() = > {
             // Get a number between 1 and 100
             let n = getRandomIntInclusive(1.100);
             if (n <= 30) {
                 alert('I won the lottery');
             } else {
                 alert('Didn't win'); }},1000);
     })
    </script>
Copy the code

(2) The promise script encapsulates an asynchronous operation in the promise.

 <script>
        var btn = document.querySelector("#btn");
    // Get a random integer between two numbers, including both numbers
    function getRandomIntInclusive(min, max) {
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min + 1)) + min; // Contain maximum value, contain minimum value
    }
    // Click the event
     btn.addEventListener('click'.function(){
         // Promise, resolve, and reject are function types.
         const p = new Promise((resolve,reject) = > {
             setTimeout(() = >{
                  let n = getRandomIntInclusive(1.100);
                  if(n<=30){
                      resolve(); // Set the promise state to "Success"
                  }else{
                      reject(); // Set the promise state to "failed"}},1000)});// Call the then method
         p.then(() = >{
             // Execute this step "successfully"
            alert('I won the lottery');
         },() = >{
             // "fail" to perform this step
            alert('Didn't win'); })})Copy the code

If you want to add the selected number after the output above:

Because n cannot be obtained directly in.then (), n is returned as the result in resolve and reject.

 // Click the event
     btn.addEventListener('click'.function(){
         // Promise, resolve, and reject are function types.
         const p = new Promise((resolve,reject) = > {
             setTimeout(() = >{
                  let n = getRandomIntInclusive(1.100);
                  if(n<=30){
                      resolve(n); // Set the promise state to "Success" and return the result value n
                  }else{
                      reject(n); // Set the promise state to "fail" and return the result value n}},1000)});// Call the then method
         // Value = value; reason = reason
         p.then((value) = >{
             // Execute successfully
            alert('I won the lottery'+value);
         },(reason) = >{
             // "failed" execution
            alert('Didn't win'+reason); })})Copy the code

4: Promise experience Ajax request:

This is an API document for the open source community, and there are many apis. Effect: Click the button to get a quote output in the console. Basic writing method:

 <script>
        var btn = document.querySelector("#btn");
    // Click the event
      btn.addEventListener('click'.function(){
         // Create an object
         const xhr = new XMLHttpRequest();
         / / initialization
         xhr.open('GET'."http://poetry.apiopen.top/sentences");
         / / send
         xhr.send();
         // Process the response result
         xhr.onreadystatechange = function(){
             if(xhr.readyState === 4) {if(xhr.status >=200 && xhr.status < 300) {// Output response body
                     console.log(xhr.response);
                 }else{
                     // Output the response status code
                     console.log(xhr.status);
                 }
             }
         }
     })
    </script>
Copy the code

Promise encapsulation:

 // Click the event
     btn.addEventListener('click'.function(){
         const p = new Promise((resolve,reject) = > {
              // Create an object
         const xhr = new XMLHttpRequest();
             / / initialization
             xhr.open('GET'."http://poetry.apiopen.top/sentences");
             / / send
             xhr.send();
             // Process the response result
             xhr.onreadystatechange = function () {
                 if (xhr.readyState === 4) {
                     if (xhr.status >= 200 && xhr.status < 300) {
                         // Output response body
                        resolve(xhr.response);
                     } else {
                         // Output the response status code
                         reject(xhr.status);
                     }
                 }
             }
         })
         p.then(value= >{
              console.log(value);
         },reason= >{
             // The console outputs a warning message
               console.warn(reason); })})Copy the code

Promise encapsulates Ajax requests:

It’s about the same as the last step. Encapsulate it in a custom function called sendAJAX ().

function sendAJAX(url) {
         return new Promise((resolve, reject) = > {
                // Create an object
                const xhr = new XMLHttpRequest();
                xhr.responseType = 'json';
                / / initialization
                xhr.open('GET', url);
                / / send
                xhr.send();
                // Process the response result
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4) {
                        if (xhr.status >= 200 && xhr.status < 300) {
                            // Output response body
                            resolve(xhr.response);
                        } else {
                            // Output the response status codereject(xhr.status); }}}}); } sendAJAX("http://poetry.apiopen.top/sentences")
     .then(value= >{
              console.log(value);
         },reason= >{
             // The console outputs a warning message
               console.warn(reason);
         })
Copy the code

6: Promise’s status changes:

The promise state represents a property [PromiseState] of the instance object. These include: (1) pending, (2) Resolved or fullfilled successfully, and (3) Rejected. The Promise object value represents another property of the instance object (PromiseResult). Holds the result of an object’s success/failure. (1) Resolved (2) Pending (3) Resolved (4) Resolved (4) Pending (5) Resolved A Promise object can only be changed once, and there is a result data whether it is successful or failed. The value is a success, and the reason is a failure.

7. Basic flow chart:

8. Promise’s API usage:

1. Promise constructor: Promise (executor) {}

(1) Executor: reject (resolve, reject) => {}. (2) resolve function: call function value => {} when the internal definition succeeds. (3) Reject: Call the reject function when internal definitions fail. Reason => {}. Note: Promise internally synchronises calls to the executor, where asynchronous operations are performed.

(onResolved, onRejected)=> {}

(1) onResolved function => {} (2) onResolved function => {} (1) onResolved function => {} (2) onResolved function => {} Note: The success callbacks specified for getting the success value and the failure callbacks for getting the failure reason are to return a new Promise object.

3. Promise. Prototype. Wanna catch method: (onRejected) = > {}

**(reason)=> {} Then () = then(undefined, onRejected)

4. Promise.resolve method: (value)=> {}

Note: If the parameter is a non-Promise object, the result is a successful PROMISE object. If the parameter is a PROMISE object, the result of the parameter determines the result of resolve.

5. Reject: (reason) => {}

Note: Only one promise object is returned regardless of what is passed in.

6. Promise. All method: (promises)=> {}

Note: Return a new promise. Promises will only be successful if all promises are successful. If one promise fails, it will fail. Failed to return that failed value.

7. Promise. Race method: (promises)=> {}

Note: Return a new promise. The result state of the first completed promise is the final result state. Here’s an example:

 let p1 = new Promise((resolve,reject) = >{
          setTimeout(() = >{
              resolve('yes');
          },1000)})let p2 = Promise.resolve('success');
      let p3 = Promise.resolve('come');

      const result = Promise.race([p1,p2,p3]);
      console.log(result);
Copy the code

Nine: Key issues facing the use of Promise:

1. How to change the state of a promise?

Resolve (value): Resolve (value): Resolved if it is currently pending. (2) Reject (reason): if the current is pending, it will become rejected. (3) Throw an exception: if it is pending, it will become rejected.

 let p1 = new Promise((resolve,reject) = >{
           // resolve('success');
         // reject('error');
          // throw 'error';
      })
Copy the code

2. If a promise specifies multiple success/failure callbacks, will they be called?

Called when a promise changes to the corresponding state.

 let p = new Promise((resolve,reject) = >{
            resolve('success');
      })
      // The first callback
      p.then(value= >{
          console.log("yes");
      })
      // The second callback
      p.then(value= >{
          console.log("oh yes");
      })
Copy the code

3. Change the state of the promiscuous function and specify the callback function.

(1) It is possible to specify the callback and then change the state, but it is also possible to change the state and then specify the callback. Call resolve(/reject() directly in the executor; Then (); (3) When will the data be available? If the state changes, the callback function will be called. If the state changes, the callback function will be called, and the data will be obtained

4. What determines the result status of the new promise returned by promise.then ()?

(1) Simple expression: the result of the callback function specified by then () is determined. (2) If the exception is thrown, the new promise will be rejected and reaon will be thrown. * If any value is returned that is not prormise, the new promise becomes resolved, and the value is the returned value. * If another new promise is returned, the result of that promise will become the result of the new promise.

Essay:

let p = new Promise((resolve,reject) = > {
            // resolve('success'); 
           // reject('No'); 
          // throw 'oh no';
      });    
      let result = p.then(value= > {
           console.log(value);
      }, reason= > {
           console.warn(reason);   
      });     
      console.log(result);
Copy the code

5. How to concatenate multiple operation tasks?

(1) Promise’s then() returns a new promise, which can be opened as a chained call to THEN (). (2) Concatenation of multiple synchronous/asynchronous tasks through chained calls of then.

 let p =new Promise((resolve,reject) = > {
          resolve("yes");
     })
     p.then(value= > {
          return new Promise((resolve,reject) = >{
              resolve("oh yes~");
          });
     }).then(value= > {
          console.log(value);
     })
Copy the code

Output: OH yes~

 let p =new Promise((resolve,reject) = > {
          resolve("yes");
     })
     p.then(value= > {
          return new Promise((resolve,reject) = >{
              resolve("oh yes~");
          });
     }).then(value= > {
          console.log(value);
     }).then(value= > {
          console.log(value);
     })
Copy the code

Output: OH yes~ undefined

6. Abnormal penetration of Promise.

(1) When using a PROMISE’s THEN chained call, you can specify a failed callback at the end. (2) Any previous operation out of the exception, will be passed to the final failure of the callback processing.

 let p =new Promise((resolve,reject) = > {
         setTimeout(() = >{
            resolve("yes");
         },1000);
     })
     p.then(value= > {
          throw 'oh No';
     }).then(value= > {
          console.log("123");
     }).then(value= > {
          console.log("456");
     }).catch(reason= >{
         console.warn(reason);
     })
Copy the code

Output: OH No

7. Break the Promise chain.

(1) When using a PROMISE’s THEN chain call, break in the middle and no longer call the following callback function. (2) Return a Promise object in the pendding state in the callback function.

Not break:

 let p =new Promise((resolve,reject) = > {
         setTimeout(() = >{
            resolve("yes");
         },1000);
     })
     p.then(value= > {
          console.log("789");
     }).then(value= > {
          console.log("123");
     }).then(value= > {
          console.log("456");
     }).catch(reason= >{
         console.warn(reason);
     })
Copy the code

Output: 789 123 456

Interrupts:

 let p =new Promise((resolve,reject) = > {
         setTimeout(() = >{
            resolve("yes");
         },1000);
     })
     p.then(value= > {
          console.log("789");
          return new Promise(() = >{});
     }).then(value= > {
          console.log("123");
     }).then(value= > {
          console.log("456");
     }).catch(reason= >{
         console.warn(reason);
     })
Copy the code

Output: 789

10. Custom encapsulation of Promise:

Packaging:

class Promise{
    // The constructor
    constructor(executor) {
          // Add the state attribute and the result value attribute
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // Define the callback property to hold the callback function with pending state
          this.callbacks = [];
           // Save the this value of the instance object
           const that = this;
          // Customize the name of the resolve function
          function resolve(data) {
        // Check whether the status is modified
        if(that.PromiseState ! = ='pending') return;
        // Change the state attribute
        that.PromiseState = 'fulfilled';  / / or resolve
        // Change the result value attribute
        that.PromiseResult = data;
        // Execute the callback function after the asynchronous task succeeds
        setTimeout(() = > {
            that.callbacks.forEach(item= >{ item.onResolved(data); })}); }// Customize the reject function
    function reject(data) {
        // Check whether the status has been modified, and return it directly
        if(that.PromiseState ! = ='pending') return;
        // Change the state attribute
        that.PromiseState = 'rejected';
        // Change the result value attribute
        that.PromiseResult = data;
        // Execute the callback function after the asynchronous task fails
        setTimeout(() = > {
            that.callbacks.forEach(item= >{ item.onRejected(data); })}); }try{
          // Call [executor function] synchronously
          executor(resolve,reject);
          }catch(e){
              // Change the Promise object to failreject(e); }}// The then method is encapsulated
    then(onResolved,onRejected){
        const that = this;
         // Check whether the callback parameter exists
         if(typeofonRejected ! = ='function'){
             onRejected = reason= >{
                 throwreason; }}if(typeofonResolved ! = ='function'){
             onResolved = value= > value;
         }
            return new Promise((resolve, reject) = > {
                // Encapsulate duplicate parts
                function callback(type){
                    try {
                        // Pass in the result value
                        let result = type(that.PromiseResult);
                        / / determine
                        if (result instanceof Promise) {
                            // If it is a Promise object
                            result.then(v= > {
                                resolve(v);
                            }, r= >{ reject(r); })}else {
                            // The result object state is [Success].resolve(result); }}catch(e) { reject(e); }}This function is fulfilled if the Promise state is fulfilled
                if (this.PromiseState === 'fulfilled') {
                    setTimeout(() = >{
                        callback(onResolved);
                    });
                }
                // Call back if the Promise state is Rejected
                if (this.PromiseState === 'rejected') {
                    setTimeout(() = >{
                        callback(onRejected);
                    });
                }
                // If the Promise state is pending, save the callback
                if (this.PromiseState === 'pending') {
                    this.callbacks.push({
                        onResolved: function () {
                            callback(onResolved);
                        },
                        onRejected: function () { callback(onRejected); }})}})/ / catch method
    catch(onRejected){
         return this.then(undefined,onRejected);
     }
    / / resolve method
    static resolve(value){
    // Return the promise object
    return new Promise((resolve,reject) = >{
       if(value instanceof Promise){
            value.then(v= >{
               resolve(v);
            },r= >{ reject(r); })}else{ resolve(value); }})}/ / reject method
    static reject(reason){
    return new Promise((resolve,reject) = >{
        reject(reason);
    });
}
    / / all methods
    static all(promises) {
        return new Promise((resolve, reject) = > {
            // Add variables
            let count = 0;
            // Store the array of successful results
            let arr = [];
            // Iterate through all
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(v= > {
                    // Being able to get in is proof of success
                    count++;
                    // Save the successful result
                    arr[i] = v;
                    // If all is successful
                    if (count === promises.length) {
                        // The status is Successfulresolve(arr); }},r= > {
                    // Can enter the proof of failurereject(r); }); }}); }/ / race method
    static race(promises) {
        return new Promise((resolve, reject) = > {
            // Iterate through all
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(v= > {
                    // Being able to get in is proof of success
                    // The status is Successful
                    resolve(v);
                }, r= > {
                    // Can enter the proof of failurereject(r); }}})); }}Copy the code

Async function:

MDN document

1. Return a promise object. 2. The result of the Promise object is determined by the return value of the async function execution. 3. The result returned by the then () method is the same as that returned by the then () method.

1. Return a non-PROMISE object with the value resolve.

 async function main(){
             return '123';
          }
          let res = main();
          console.log(res);
Copy the code

2. If a Promise object is returned, it is determined by the result returned:

Such as:

 async function main(){
             return new Promise((resolve,reject) = >{
                 reject('NO');
             });
          }
          let res = main();
          console.log(res);

Copy the code

3. Failed to throw an exception:

 async function main(){
             return new Promise((resolve,reject) = >{
                 reject('NO');
             });
          }
          let res = main();
          console.log(res);
Copy the code

Await expression:

MDN document

1. The expression to the right of await is usually a Promise object, but can also be other values. 2. If the expression is a Promise object,await returns the success value of the promise. 3. If the expression is any other value, use this value as the return value of the await directly.

Note:

1. Await must be written in async functions, but async functions may not have await. 2. If the promise of the await fails, an exception is thrown, via the try… Catch Catch processing.

1. On the right is the Promise object:

 async function works(){
             let p = new Promise((resolve,reject)=>{
                 resolve('oh yes')
             })
             let res = await p;
             console.log(res);
         }
         works();
Copy the code

Result: Oh yes

2. Other values on the right:

  async function works(){
             let p = new Promise((resolve,reject) = >{
                 resolve('oh yes')})// let res = await p;
           let res = await 100;
             console.log(res);
         }
         works();
Copy the code

Results: 100

3. If the promise is a failure state:

 async function works(){
             let p = new Promise((resolve,reject) = >{
                // resolve('oh yes')
                reject('err');
             })          
            try{
                let res = await p;
            }catch(e){
                console.log(e);
            }
         }
         works();
Copy the code

Sending Ajax requests with async and await:

Effect: Click the button to get a quote.

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta  name="viewport" content="width=device-width, "> <title>Document</title> </head> <body> <button id=" BTN "> </button> <script> function SendAJAX (URL) {return new Promise((resolve, reject) => {// Create object const XHR = new XMLHttpRequest(); xhr.responseType = 'json'; // Initialize xhr.open('GET', url); / / XHR. The send (); Xhr.onreadystatechange = function () {if (xhr.readystate === = 4) {if (xhr.status >= 200 && xhr.status < 300) { Resolve (xhr.response); } else {reject(xhr.status); // reject(xhr.status); }}}}); } var btn = document.querySelector("#btn"); btn.addEventListener('click',async function(){ let word = await sendAJAX("http://poetry.apiopen.top/sentences"); console.log(word); }) </script> </body> </html>Copy the code