This is the 7th day of my participation in Gwen Challenge

To strengthen and consolidate the understanding of Promise, learn to encapsulate a Promise class library of your own.

Then, if you are not clear about the basic knowledge of Promise, you can take a look at this Promise to learn – basic knowledge

1. Promise class library encapsulation

class Promise {
    // constructor
    constructor(executor) {
      // Declare the constructor
      // Add attributes
      this.PromiseState = 'pending'
      this.PromiseResult = null
      // Declare attributes
      this.callbacks = [];
      // Save the value of this for the instance object
      const self = this;
      function resolve(data) {
            // Determine the status. The status can be changed only once
            if(self.PromiseState ! = ='pending') return ;
            // Change the object status PromiseState
            self.PromiseState = 'fulfilled';
            // Set the result value of the object to PromiseResult
            self.PromiseResult = data;
            // Call the successful callback function
            setTimeout(() = > {
                self.callbacks.forEach(item= > {
                    item.onResolved(data)
                })
            })
      }
      function reject(data) {
            // Determine the status. The status can be changed only once
            if(self.PromiseState ! = ='pending') return ;
            // Change the object status PromiseState
            self.PromiseState = 'rejected'
            // Set the result value of the object to PromiseResult
            self.PromiseResult = data
            // Call the failed callback function
            setTimeout(() = > {
                self.callbacks.forEach(item= > {
                    item.onRejected(data)
                })
            })
      }
      try {
            // Synchronous call
            executor(resolve, reject)
      } catch (error) {
           reject(error)
      }
    }
    // then method encapsulation
    then(onResolved, onRejected) {
        const self = this;
        // Determine the callback parameters
        if (typeofonRejected ! = ='function') {
            onRejected = reason= > {
                throwreason; }}if (typeofonResolved ! = ='function') {
            onResolved = value= > value;
        }
        return new Promise((resolve, reject) = > {
            // Encapsulate the function
            function callback(type) {
                try {
                   // Get the result of executing the callback function
                   let result = type(self.PromiseResult)
                   / / determine
                   if(result instanceof Promise) {
                       // If it is a promise object
                       result.then(v= > {
                          resolve(v)
                       }, r= > {
                          reject(r)
                       })
                   } else {
                       // The object state of the result is changed to success
                       resolve(result)
                   }
                } catch(e) {
                    reject(e)
                }
            }
            // Call the callback function
            if(this.PromiseState === 'fulfilled') {
                setTimeout(() = > {
                    callback(onResolved)
                })
            }
            if(this.PromiseState === 'rejected') {
                setTimeout(() = > {
                    callback(onRejected)
                })
            }
            if(this.PromiseState === 'pending') {
              // Save the callback function
              this.callbacks.push({
                  onResolved: function() {
                      callback(onResolved)
                  },
                  onRejected: function() {
                      callback(onRejected)
                  }
              })
            }
        })
    }
    // Catch method encapsulation
    catch(onRejected) {
        return this.then(undefined, onRejected)
    }
    / / resolve method
    static resolve(value) {
        return new Promise((resolve, reject) = > {
            if (value instanceof Promise) {
                value.then(v= > {
                    resolve(v)
                }, r= > {
                    reject(r)
                })
            } else {
                resolve(value)
            }
        })
     }
     // reject encapsulation
    static reject(reason) {
        return new Promise((resolve, reject) = > {
            reject(reason)
        })
    }
    // all method encapsulation
    static all(promise) {
        let count = 0;
        let arr = [] // Save the successful result
        return new Promise((resolve, reject) = > {
            for(let i=0; i<promise.length; i++) {
                promise[i].then(v= >{
                      // Each promise object succeeds
                      count++;
                      arr[i] = v;
                      if(count === promise.length) {
                          resolve(arr)
                      }
                }, r= >{
                    reject(r)
                })
            }
        })
    }
    // race method encapsulation
    static race(promise) {
        return new Promise((resolve,reject) = > {
            for(let i=0; i<promise.length; i++) { promise[i].then(v= > {
                    resolve(v)
                },r= > {
                    reject(r)
                })
            }
        })
    }
}

Copy the code

The test code

let p = new Promise((resolve, reject) = > {
        setTimeout(() = > {
           reject('ok')},100)})const res = p.then(value= > {
        console.log(value)
    }, reason= > {
        console.warn(reason)
    })
    console.log(res)
const res2 = p.catch(reason= > {
    console.log(reason)
})
    console.log(res2)


let p4 = new Promise((resolve, reject) = > {
    resolve('ok')
    console.log(111)
})
    p4.then(value= > {
        console.log(222)})console.log(333)
Copy the code

Note that the code inside the callback is executed asynchronously,

You can see the following code execution result:

let p = new Promise((resolve, reject) = > {
    resolve('ok')
    console.log(111)
})
    p.then(value= > {
        console.log(222)})console.log(333)
Copy the code

The answer is: 111 — > 333 — > 222

Synchronous code executes first, and asynchronous code waits until the synchronous code finishes executing

2, async function

1, the function returns a Promise object

2. The result of the Promise object is determined by the return value of the async function

3, await expression

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 some other value, return this value directly as await

Note: await must be written in async functions, but async functions can have no await

Note: If the await promise fails, an exception will be thrown, requiring a try… Catch catch

async function main() {
    let p = new Promise((resolve, reject) = > {
        resolve('ok')})// On the right of 1 is the promise case
    let res = await p;
    // 2, other types of data on the right
    let res2 = await 20;
    // If promises are a state of failure, reject('error') is commented out above
    try {
        let res3 = await p
    } catch(e) {
        console.log(e)
    }
}
 main()
Copy the code

4. Async and await

/** * read multiple file contents and concatenate */
const fs = require('fs')
const util = require('util')
const mineReadFile = util.promisify(fs.readFile)
async function myReadFile() {
    // Read the first file
    try {
        let data1 = await mineReadFile('./package/content1.txt')
        let data2 = await mineReadFile('./package/content2.txt')
        let data3 = await mineReadFile('./package/content3.txt')
        console.log(data1 + data2 + data3)
    }catch(e) {
       console.log(e)
    }
}
mineReadFile()
Copy the code
/** * encapsulates AJAX interface requests *@param {*} url 
 */
function sendAjax(url) {
    return new Promise((resolve, reject) = > {
        const xhr = new XMLHttpRequest()
        xhr.open('GET', url);
        xhr.send()
        xhr.onreadystatechange = function() {
            if(xhr.readyState === 4) {
                if(xhr.status >=200 && xhr.status < 300) {
                    resolve(xhr.response)
                } else {
                    reject(xhr.status)
                }
            }
        }
    })
}

xxxx.addEventListener('click'.async function() {
    let content = await sendAjax('https://api.apiopen.top/getJoke')
    console.log(content)
})

Copy the code

5. Talk about the difference between AJAX, AXIOS and FETCH

1, AJAX: asynchronous network request, it can realize the page without refreshing the request data. In the past, the page form submitted data, after the user clicks “submit” button, the page will be forced to refresh, the experience is very unfriendly.

var request = new XMLHttpRequest(); / / create the XMLHttpRequest object / / ajax is asynchronous, set the callback function request. The onreadystatechange = function () {/ / state changes, If (request.status === 200) {responseText () {responseText () {responseText (); return success(request.responseText); } else {return fail(request.status);} else {return fail(request.status); }} else {// HTTP requests continue... }} / / send the request, the request. The open (' GET 'and'/API/categories); Request.setrequestheader (" content-type ", "application/json") // Set the request header request.send(); // At this point, the request is officially issuedCopy the code

2. AXIOS: AXIOS is an HTTP client based on Promise for browsers and NodeJS, which is essentially a wrapper around native XHR, but it’s an implementation of Promise that meets the latest ES specification

  • Create XMLHttpRequests from the browser
  • Create HTTP requests from Node.js
  • Supporting Promise API
  • Intercept requests and responses
  • Transform request data and response data
  • Cancel the request
  • Automatically convert JSON data
  • The client supports XSRF defense

Because AXIos has a clean design, a simple API, support for browsers and Nodes,

3. FETCH: FETCH is a new technology product of front-end development

  • When an HTTP status code representing an error is received, the Promise returned from fetch() is not marked as reject, even if the HTTP response’s status code is 404 or 500. Instead, it marks the Promise state as resolve (but sets the OK attribute of the return value of Resolve to false), and only as Reject when the network fails or the request is blocked.
  • By default, FETCH does not send or receive any cookies from the server, which can result in unauthenticated requests if the site relies on the user session (the Credentials option must be set to send cookies).

Fetch represents a more advanced technical direction, but the current compatibility is not very good, so we should be careful when using it in the project.