This is my 24th day of the Gwen Challenge

What is the Promise?

  1. Promise is a new solution for asynchronous programming in JS. (The old scheme used to just use the callback function)
  2. Syntactically, a promise is a constructor.
  3. Functionally, the Promise object is used to encapsulate an asynchronous operation and can return a success or failure value.
  4. Common asynchronous operations in JS: timer, AJAX is generally also asynchronous operations (can also be synchronous), callback functions can be understood as asynchronous (not strictly asynchronous operation)… And so on.

The rest is all synchronous processing

Why use Promise:

  1. Promise is more flexible with callback functions. The old callback function must be specified before starting the asynchronous task.
  2. Promise: Start the asynchronous task => return the Promise object => Bind the callback function to the Promise object (you can even specify multiple callback functions after the asynchronous task ends)
  3. Promise supports chained calls that solve the callback hell problem. (Callback hell is the nested use of multiple layers of callback functions, known as nesting doll, which makes reading and exception handling difficult.)

Iii. Promise:

Effect: click on a button and 30% of the time you will be shown winning. Implementation: click the button to get a random number between 1 and 100, less than or equal to 30 output winning, otherwise the output is not in. During the timer to simulate asynchronous operation, in the timer to perform the judgment. (1) Basic writing:

<button id="btn">click</button>
Copy the code
    <script>
        var btn = document.querySelector("#btn");
    // This function returns a random integer between two numbers, including two 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('Win the lottery');
             } else {
                 alert('Didn't win the lottery'); }},1000);
     })
    </script>
Copy the code

(2) Promise writing, encapsulate an asynchronous operation in the promise.

    <script>
        var btn = document.querySelector("#btn");
    // Get a random integer between two numbers, including two 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, reject, 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 "fail"}},1000)});// Call the then method
         p.then(() = >{
             // Execute this step "successfully"
            alert('Win the lottery');
         },() = >{
             // "failed" to execute this step
            alert('Didn't win the lottery'); })})Copy the code

In resolve and reject, n is returned because n is not available in. Then ().

 // Click the event
     btn.addEventListener('click'.function(){
         // Promise, resolve, reject, 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 "failed" and return the result value n}},1000)});// Call the then method
         // Value = value; reason = reason
         p.then((value) = >{
             // "Successful" execution
            alert('Win the lottery'+value);
         },(reason) = >{
             // "failed" execution
            alert('Didn't win the lottery'+reason); })})Copy the code

Iv: Promise experience ajax request:

This is an API documentation for the open source community, with many apis. Effect: Click the button to get a quote in console output. Basic writing:

 <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) {// Outputs the response body
                     console.log(xhr.response);
                 }else{
                     // Outputs 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) {
                         // Outputs the response body
                        resolve(xhr.response);
                     } else {
                         // Outputs the response status code
                         reject(xhr.status);
                     }
                 }
             }
         })
         p.then(value= >{
              console.log(value);
         },reason= >{
             // The console outputs warning messages
               console.warn(reason); })})Copy the code

If the interface is incorrectly written:

Five: Promise encapsulates ajax requests:

The last step is pretty much the same. 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) {
                            // Outputs the response body
                            resolve(xhr.response);
                        } else {
                            // Outputs the response status codereject(xhr.status); }}}}); } sendAJAX("http://poetry.apiopen.top/sentences")
     .then(value= >{
              console.log(value);
         },reason= >{
             // The console outputs warning messages
               console.warn(reason);
         })
Copy the code

Vi. State change of promise:

The promise state represents a property of the instance object [PromiseState]. PromiseResult = PromiseResult = PromiseResult = PromiseResult = PromiseResult = PromiseResult = PromiseResult Holds the result of the object’s success/failure. (1) Pending changes to Resolved (2) Pending changes to Rejected note: A promise object can only be changed once, and there will be a result data whether it succeeds or fails. The successful one is called value, and the failed one is called Reason.

Basic flow chart:

Viii. API use of Promise:

Promise (executor) {}

Executor (resolve, reject) => {} (2) Resolve function: call value => {} when internal definition succeeds. (3) Reject function: call reason when internal definition fails => {}. Note: Promise internally calls executor synchronously, and asynchronous operations are performed in the executor.

Prototype. Then (onResolved, onRejected)=> {}

(1) onResolved function (value) => {} (2) onResolved function (reason) => {} Note: The successful callback specified for a successful value and the failure callback specified for a failed Reason returns a new Promise object.

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

**(reason)=> {}** Note: this is only a failed call to onRejected. Then () = undefined, onRejected.

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

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

5. Promise. Reject method: (reason) => {}

Note: No matter what is passed in, only a failed promise object is returned.

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

Promises: promises: an array of n promises: Promises return a new promise. Promises work only when all promises work. Promises fail only when one fails. Failed returns the failed value.

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

Promises: Promises return a new promise. The outcome state of the first promise made is the final outcome 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 in using Promise:

1. How to change the state of promise?

(1) Resolve (value): Resolved if it is pending. (2) Reject (reason): If it is pending, it changes to Rejected. (3) Throw: If the value is pending, it changes to Rejected.

 let p1 = new Promise((resolve,reject) = >{
           // resolve('success');
         // reject('error');
          // throw 'error';
      })
Copy the code
2. Will multiple success/failure callbacks specified by a promise be called?

This is called whenever 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. Who is first to change the promiseT state or specify callback functions?

(1) Both are possible. The normal case is to specify the callback and then change the state, but it is also possible to change the state and then specify the callback

(2) How to change the state before specifying the callback? Resolve (/reject()); ② Delay calling then() for longer; (3) When will the data be available? If the state is changed first, the callback function will be called and the data will be returned

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

Then () specifies the result of the execution of the callback function. (1) Reaon = rejected; (2) Reaon = rejected; * If an arbitrary value is returned that is not Prormise, the new Promise becomes resolved, and value is the returned value. * If another new promise is returned, the result of that promise becomes 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 does promise string together multiple action tasks?

(1) Promise’s then() returns a new promise, which can be opened as a chain call to then(). (2) Chain multiple synchronous/asynchronous tasks through chaining calls to 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

Command 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

Oh yes~ undefined

6. Abnormal penetration of promise.

(1) When using promise’s then chain call, you can specify the failed callback at the end. (2) Any previous operation is abnormal, will be passed to the last failed 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 promise’s then chain call, it breaks in the middle and does not call subsequent callback functions. (2) Method: Return a Pendding Promise object in the callback.

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

789 123 456 is displayed

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

The output is 789

X. Custom packaging of Promise:

1. Initial structure construction:
 // Define the function Promise
     function Promise(executor){}// Add the then method
     Promise.prototype.then = function(onResolved,onRejected){}Copy the code

Note: The Prototype property gives you the ability to add properties and methods to an object.

2. Build resolve and reject structures:
 // Define the function Promise
     function Promise(executor){
          // Create a custom resolve function
          function resolve(data){}// Customize reject
          function reject(data){}// call [executor function]
          executor(resolve,reject);          
     }
     // Add the then method
     Promise.prototype.then = function(onResolved,onRejected){}Copy the code
Implement resolve and reject functions:
 // Define the function Promise
     function Promise(executor){
          // Add status attributes and result value attributes
          this.PromiseState = 'pending';
          this.PromiseResult = null;
           // Save the instance object's this value
           const that = this;
          // Create a custom resolve function
          function resolve(data){
             // Change the state property
             that.PromiseState = 'fulfilled';  / / or resolved
             // Change the result value attribute
             that.PromiseResult =data;
          }
          // Customize reject
          function reject(data){
              // Change the state property
             that.PromiseState = 'rejected';  
            // Change the result value attribute
             that.PromiseResult =data;
          }
          // call [executor function]
          executor(resolve,reject);          
     }
     // Add the then method
     Promise.prototype.then = function(onResolved,onRejected){}Copy the code
4. Throw an exception to change state:

Use try{}catch(){} with throw.

// Define the function Promise
 function Promise(executor){
      // Add status attributes and result value attributes
      this.PromiseState = 'pending';
      this.PromiseResult = null;
       // Save the instance object's this value
       const that = this;
      // Create a custom resolve function
      function resolve(data){
         // Change the state property
         that.PromiseState = 'fulfilled';  / / or resolve
         // Change the result value attribute
         that.PromiseResult =data;
      }
      // Customize reject
      function reject(data){
          // Change the state property
         that.PromiseState = 'rejected';  
        // Change the result value attribute
         that.PromiseResult =data;
      }

      try{
      // call [executor function]
      executor(resolve,reject);
      }catch(e){
          // Change the Promise object to failreject(e); }}// Add the then method
 Promise.prototype.then = function(onResolved,onRejected){}Copy the code

Note the throw statement throws an error.

5. Set the Promise object state to be changed only once:

Just add a judgment.

// Define the function Promise
     function Promise(executor){
          // Add status attributes and result value attributes
          this.PromiseState = 'pending';
          this.PromiseResult = null;
           // Save the instance object's this value
           const that = this;
          // Create a custom resolve function
          function resolve(data){
            // Check whether the status has been changed and return directly
            if(that.PromiseState ! = ='pending') return;
             // Change the state property
             that.PromiseState = 'fulfilled';  / / or resolve
             // Change the result value attribute
             that.PromiseResult =data;
          }
          // Customize reject
          function reject(data){
             // Check whether the status has been changed and return directly
            if(that.PromiseState ! = ='pending') return;
              // Change the state property
             that.PromiseState = 'rejected';  
            // Change the result value attribute
             that.PromiseResult =data;
          }

          try{
          // call [executor function]
          executor(resolve,reject);
          }catch(e){
              // Change the Promise object to failreject(e); }}// Add the then method
     Promise.prototype.then = function(onResolved,onRejected){}Copy the code
6. The then () method executes the callback:
  // Define the function Promise
     function Promise(executor){
          // Add status attributes and result value attributes
          this.PromiseState = 'pending';
          this.PromiseResult = null;
           // Save the instance object's this value
           const that = this;
          // Create a custom resolve function
          function resolve(data){
            // Check whether the status has been changed
            if(that.PromiseState ! = ='pending') return;
             // Change the state property
             that.PromiseState = 'fulfilled';  / / or resolve
             // Change the result value attribute
             that.PromiseResult =data;
          }
          // Customize reject
          function reject(data){
             // Check whether the status has been changed and return directly
            if(that.PromiseState ! = ='pending') return;
              // Change the state property
             that.PromiseState = 'rejected';  
            // Change the result value attribute
             that.PromiseResult =data;
          }

          try{
          // call [executor function]
          executor(resolve,reject);
          }catch(e){
              // Change the Promise object to failreject(e); }}// Add the then method
     Promise.prototype.then = function(onResolved,onRejected){
         // If the Promise state is fulfilled, this function will be callback
         if(this.PromiseState === 'fulfilled') {// Pass in the result value
            onResolved(this.PromiseResult);
         }
         // Call this function if the Promise state is Rejected
         if(this.PromiseState === 'rejected') {// Pass in the result value
            onRejected(this.PromiseResult); }}Copy the code
7. Execute asynchronous task callback:

Asynchronous tasks typically call back before changing state. So the code in step 6 cannot execute the asynchronous callback in the following order:

// Define the function Promise
 function Promise(executor){
      // Add status attributes and result value attributes
      this.PromiseState = 'pending';
      this.PromiseResult = null;
      // Define the callback attribute to hold the pending state callback function
      this.callback = {};
       // Save the instance object's this value
       const that = this;
      // Create a custom resolve function
      function resolve(data){
        // Check whether the status has been changed
        if(that.PromiseState ! = ='pending') return;
         // Change the state property
         that.PromiseState = 'fulfilled';  / / or resolve
         // Change the result value attribute
         that.PromiseResult =data;
          // Execute the callback function after the asynchronous task succeeds
          if(that.callback.onResolved){ that.callback.onResolved(data); }}// Customize reject
      function reject(data){
         // Check whether the status has been changed and return directly
        if(that.PromiseState ! = ='pending') return;
          // Change the state property
         that.PromiseState = 'rejected';  
        // Change the result value attribute
         that.PromiseResult =data;
         // Execute the callback function when the asynchronous task fails
         if(that.callback.onRejected){ that.callback.onRejected(data); }}try{
      // call [executor function]
      executor(resolve,reject);
      }catch(e){
          // Change the Promise object to failreject(e); }}// Add the then method
 Promise.prototype.then = function(onResolved,onRejected){
     // If the Promise state is fulfilled, this function will be callback
     if(this.PromiseState === 'fulfilled') {// Pass in the result value
        onResolved(this.PromiseResult);
     }
     // Call this function if the Promise state is Rejected
     if(this.PromiseState === 'rejected') {// Pass in the result value
        onRejected(this.PromiseResult);
     }
      // If the Promise state is pending, save the callback function
      if(this.PromiseState === 'pending') {this.callback = {
            onResolved: onResolved,
            onRejected: onRejected
        }
     }
 }
Copy the code
8. Can execute multiple callbacks:

When you specify multiple callbacks in step 7, the last then callback overwrites the previous one, as follows:

// Define the function Promise
     function Promise(executor){
          // Add status attributes and result value attributes
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // Define the callback attribute to hold the pending state callback function
          this.callbacks = [];
           // Save the instance object's this value
           const that = this;
          // Create a custom resolve function
          function resolve(data){
            // Check whether the status has been changed
            if(that.PromiseState ! = ='pending') return;
             // Change the state property
             that.PromiseState = 'fulfilled';  / / or resolve
             // Change the result value attribute
             that.PromiseResult =data;
              // Execute the callback function after the asynchronous task succeeds
              that.callbacks.forEach(item= >{ item.onResolved(data); })}// Customize reject
          function reject(data){
             // Check whether the status has been changed and return directly
            if(that.PromiseState ! = ='pending') return;
              // Change the state property
             that.PromiseState = 'rejected';  
            // Change the result value attribute
             that.PromiseResult =data;
             // Execute the callback function when the asynchronous task fails
            that.callbacks.forEach(item= >{ item.onRejected(data); })}try{
          // call [executor function]
          executor(resolve,reject);
          }catch(e){
              // Change the Promise object to failreject(e); }}// Add the then method
     Promise.prototype.then = function(onResolved,onRejected){
         // If the Promise state is fulfilled, this function will be callback
         if(this.PromiseState === 'fulfilled') {// Pass in the result value
            onResolved(this.PromiseResult);
         }
         // Call this function if the Promise state is Rejected
         if(this.PromiseState === 'rejected') {// Pass in the result value
            onRejected(this.PromiseResult);
         }
          // If the Promise state is pending, save the callback function
          if(this.PromiseState === 'pending') {this.callbacks.push({
                onResolved: onResolved,
                onRejected: onRejected
            })
         }
     }
Copy the code

ForEach () method

Then ();

Where there is an implementation in then () that returns the result:

const result = p.then(value= > {
          console.log(value);
     },reason= > {
         console.warn(reason);
     }) 
console.log(result);
Copy the code

Solution:

// Define the function Promise
function Promise(executor){
          // Add status attributes and result value attributes
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // Define the callback attribute to hold the pending state callback function
          this.callbacks = [];
           // Save the instance object's this value
           const that = this;
          // Create a custom resolve function
          function resolve(data){
            // Check whether the status has been changed
            if(that.PromiseState ! = ='pending') return;
             // Change the state property
             that.PromiseState = 'fulfilled';  / / or resolve
             // Change the result value attribute
             that.PromiseResult =data;
              // Execute the callback function after the asynchronous task succeeds
              that.callbacks.forEach(item= >{ item.onResolved(data); })}// Customize reject
          function reject(data){
             // Check whether the status has been changed and return directly
            if(that.PromiseState ! = ='pending') return;
              // Change the state property
             that.PromiseState = 'rejected';  
            // Change the result value attribute
             that.PromiseResult =data;
             // Execute the callback function when the asynchronous task fails
            that.callbacks.forEach(item= >{ item.onRejected(data); })}try{
          // call [executor function]
          executor(resolve,reject);
          }catch(e){
              // Change the Promise object to failreject(e); }}// Add the then method
     Promise.prototype.then = function (onResolved, onRejected) {
            return new Promise((resolve, reject) = > {
                // If the Promise state is fulfilled, this function will be callback
                if (this.PromiseState === 'fulfilled') {
                    try {
                        // Get the result of callback function execution
                        let result = onResolved(this.PromiseResult);
                        / / determine
                        if (result instanceof Promise) {
                            // If it is a Promise object
                            result.then(v= > {
                                resolve(v);
                            }, r= >{ reject(r); })}else {
                            // Result object status is [success]resolve(result); }}catch(e) { reject(e); }}// Call this function if the Promise state is Rejected
                if (this.PromiseState === 'rejected') {
                    // Pass in the result value
                    onRejected(this.PromiseResult);
                }
                // If the Promise state is pending, save the callback function
                if (this.PromiseState === 'pending') {
                    this.callbacks.push({
                        onResolved: onResolved,
                        onRejected: onRejected
                    })
                }
            })
        }
Copy the code

Note: The instanceof operator is used to check whether the constructor’s prototype property appears on the prototype chain of an instance object.

Then ();

(´ཀ ‘” Angle) Performing the asynchronous task in step 9 returns a pending state. Solution:

// Define the function Promise
function Promise(executor){
          // Add status attributes and result value attributes
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // Define the callback attribute to hold the pending state callback function
          this.callbacks = [];
           // Save the instance object's this value
           const that = this;
          // Create a custom resolve function
          function resolve(data){
            // Check whether the status has been changed
            if(that.PromiseState ! = ='pending') return;
             // Change the state property
             that.PromiseState = 'fulfilled';  / / or resolve
             // Change the result value attribute
             that.PromiseResult =data;
              // Execute the callback function after the asynchronous task succeeds
              that.callbacks.forEach(item= >{ item.onResolved(data); })}// Customize reject
          function reject(data){
             // Check whether the status has been changed and return directly
            if(that.PromiseState ! = ='pending') return;
              // Change the state property
             that.PromiseState = 'rejected';  
            // Change the result value attribute
             that.PromiseResult =data;
             // Execute the callback function when the asynchronous task fails
            that.callbacks.forEach(item= >{ item.onRejected(data); })}try{
          // call [executor function]
          executor(resolve,reject);
          }catch(e){
              // Change the Promise object to failreject(e); }}// Add the then method
     Promise.prototype.then = function (onResolved, onRejected) {
         const that = this;
            return new Promise((resolve, reject) = > {
                // If the Promise state is fulfilled, this function will be callback
                if (this.PromiseState === 'fulfilled') {
                    try {
                        // Pass in the result value
                        let result = onResolved(this.PromiseResult);
                        / / determine
                        if (result instanceof Promise) {
                            // If it is a Promise object
                            result.then(v= > {
                                resolve(v);
                            }, r= >{ reject(r); })}else {
                            // Result object status is [success]resolve(result); }}catch(e) { reject(e); }}// Call this function if the Promise state is Rejected
                if (this.PromiseState === 'rejected') {
                    // Pass in the result value
                    onRejected(this.PromiseResult);
                }
                // If the Promise state is pending, save the callback function
                if (this.PromiseState === 'pending') {
                    this.callbacks.push({
                        onResolved: function () {
                            try {
                                // Execute the success callback
                                let result = onResolved(that.PromiseResult);
                                / / determine
                                if (result instanceof Promise) {
                                    result.then(v= > {
                                        resolve(v);
                                    }, r= >{ reject(r); })}else{ resolve(result); }}catch(e) { reject(e); }},onRejected: function () {
                            try {
                                // Execute the success callback
                                let result = onRejected(that.PromiseResult);
                                / / determine
                                if (result instanceof Promise) {
                                    result.then(v= > {
                                        resolve(v);
                                    }, r= >{ reject(r); })}else{ resolve(result); }}catch(e){ reject(e); }}})}})}Copy the code
11. Improve then () method and optimization:
// Define the function Promise
function Promise(executor){
          // Add status attributes and result value attributes
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // Define the callback attribute to hold the pending state callback function
          this.callbacks = [];
           // Save the instance object's this value
           const that = this;
          // Create a custom resolve function
          function resolve(data){
            // Check whether the status has been changed
            if(that.PromiseState ! = ='pending') return;
             // Change the state property
             that.PromiseState = 'fulfilled';  / / or resolve
             // Change the result value attribute
             that.PromiseResult =data;
              // Execute the callback function after the asynchronous task succeeds
              that.callbacks.forEach(item= >{ item.onResolved(data); })}// Customize reject
          function reject(data){
             // Check whether the status has been changed and return directly
            if(that.PromiseState ! = ='pending') return;
              // Change the state property
             that.PromiseState = 'rejected';  
            // Change the result value attribute
             that.PromiseResult =data;
             // Execute the callback function when the asynchronous task fails
            that.callbacks.forEach(item= >{ item.onRejected(data); })}try{
          // call [executor function]
          executor(resolve,reject);
          }catch(e){
              // Change the Promise object to failreject(e); }}// Add the then method
     Promise.prototype.then = function (onResolved, onRejected) {
         const that = this;
            return new Promise((resolve, reject) = > {
                // Encapsulate the repeating 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 {
                            // Result object status is [success]resolve(result); }}catch(e) { reject(e); }}// If the Promise state is fulfilled, this function will be callback
                if (this.PromiseState === 'fulfilled') {
                    callback(onResolved);
                }
                // Call this function if the Promise state is Rejected
                if (this.PromiseState === 'rejected') {
                    callback(onRejected);
                }
                // If the Promise state is pending, save the callback function
                if (this.PromiseState === 'pending') {
                    this.callbacks.push({
                        onResolved: function () {
                            callback(onResolved);
                        },
                        onRejected: function () { callback(onRejected); }})}})}Copy the code
12. Realize catch method and exception penetration:
// Define the function Promise
function Promise(executor){
          // Add status attributes and result value attributes
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // Define the callback attribute to hold the pending state callback function
          this.callbacks = [];
           // Save the instance object's this value
           const that = this;
          // Create a custom resolve function
          function resolve(data){
            // Check whether the status has been changed
            if(that.PromiseState ! = ='pending') return;
             // Change the state property
             that.PromiseState = 'fulfilled';  / / or resolve
             // Change the result value attribute
             that.PromiseResult =data;
              // Execute the callback function after the asynchronous task succeeds
              that.callbacks.forEach(item= >{ item.onResolved(data); })}// Customize reject
          function reject(data){
             // Check whether the status has been changed and return directly
            if(that.PromiseState ! = ='pending') return;
              // Change the state property
             that.PromiseState = 'rejected';  
            // Change the result value attribute
             that.PromiseResult =data;
             // Execute the callback function when the asynchronous task fails
            that.callbacks.forEach(item= >{ item.onRejected(data); })}try{
          // call [executor function]
          executor(resolve,reject);
          }catch(e){
              // Change the Promise object to failreject(e); }}// Add the then method
     Promise.prototype.then = function (onResolved, onRejected) {
         const that = this;
         // Check whether the callback argument exists
         if(typeofonRejected ! = ='function'){
             onRejected = reason= >{
                 throwreason; }}if(typeofonResolved ! = ='function'){
             onResolved = value= > value;
         }
            return new Promise((resolve, reject) = > {
                // Encapsulate the repeating 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 {
                            // Result object status is [success]resolve(result); }}catch(e) { reject(e); }}// If the Promise state is fulfilled, this function will be callback
                if (this.PromiseState === 'fulfilled') {
                    callback(onResolved);
                }
                // Call this function if the Promise state is Rejected
                if (this.PromiseState === 'rejected') {
                    callback(onRejected);
                }
                // If the Promise state is pending, save the callback function
                if (this.PromiseState === 'pending') {
                    this.callbacks.push({
                        onResolved: function () {
                            callback(onResolved);
                        },
                        onRejected: function () { callback(onRejected); }})}})}// Add the catch method
     Promise.prototype.catch = function(onRejected){
         return this.then(undefined,onRejected);
     }
Copy the code

Note: the typeof operator returns a string representing the typeof the unevaluated operand.

13. Wrap the promise.resolve () method:

Class version encapsulation: Final encapsulation:

class Promise{
    // constructor
    constructor(executor) {
          // Add status attributes and result value attributes
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // Define the callback attribute to hold the pending state callback function
          this.callbacks = [];
           // Save the instance object's this value
           const that = this;
          // Create a custom resolve function
          function resolve(data) {
        // Check whether the status has been changed
        if(that.PromiseState ! = ='pending') return;
        // Change the state property
        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 reject
    function reject(data) {
        // Check whether the status has been changed and return directly
        if(that.PromiseState ! = ='pending') return;
        // Change the state property
        that.PromiseState = 'rejected';
        // Change the result value attribute
        that.PromiseResult = data;
        // Execute the callback function when the asynchronous task fails
        setTimeout(() = > {
            that.callbacks.forEach(item= >{ item.onRejected(data); })}); }try{
          // call [executor function]
          executor(resolve,reject);
          }catch(e){
              // Change the Promise object to failreject(e); }}//then method encapsulation
    then(onResolved,onRejected){
        const that = this;
         // Check whether the callback argument exists
         if(typeofonRejected ! = ='function'){
             onRejected = reason= >{
                 throwreason; }}if(typeofonResolved ! = ='function'){
             onResolved = value= > value;
         }
            return new Promise((resolve, reject) = > {
                // Encapsulate the repeating 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 {
                            // Result object status is [success]resolve(result); }}catch(e) { reject(e); }}// If the Promise state is fulfilled, this function will be callback
                if (this.PromiseState === 'fulfilled') {
                    setTimeout(() = >{
                        callback(onResolved);
                    });
                }
                // Call this function if the Promise state is Rejected
                if (this.PromiseState === 'rejected') {
                    setTimeout(() = >{
                        callback(onRejected);
                    });
                }
                // If the Promise state is pending, save the callback function
                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 success result array
            let arr = [];
            // go through all of them
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(v= > {
                    // The entry is deemed a success
                    count++;
                    // Save the result successfully
                    arr[i] = v;
                    // If all are successful
                    if (count === promises.length) {
                        // The status is successfulresolve(arr); }},r= > {
                    // Can enter to prove that it is a failurereject(r); }); }}); }/ / race method
    static race(promises) {
        return new Promise((resolve, reject) = > {
            // go through all of them
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(v= > {
                    // The entry is deemed a success
                    // The status is successful
                    resolve(v);
                }, r= > {
                    // Can enter to prove that it is a failurereject(r); }}})); }}Copy the code

Xi. Async functions:

MDN document

1. The function returns a Promise object. 2. The result of the Promise object is determined by the return value executed by the async function. 3. Then () returns the same result.

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 the return is a Promise object, it depends on the return result:

Such as:

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

3. Throwing an exception also fails:
 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 it can be any other value. 2. If the expression is a Promise object,await returns the promise success value. 3. If the expression is another value, return this value directly as await.

Note:

1. Await must be written in async functions, but async functions can have no await. 2. If an await promise fails, an exception will be thrown, which requires a 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 promise is a failed 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

Xiii. Ajax request with async and await

Effect: Click the button to get a quote.

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Document</title>
</head>
<body>
    <button id="btn">Get a quote</button>
    <script>
        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) {
                            // Outputs the response body
                            resolve(xhr.response);
                        } else {
                            // Outputs the response status codereject(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

Xiv. Summary:

I just want to say…