javaScript asynchronous programming

Posted by r3dk1t on Mon, 21 Feb 2022 05:06:51 +0100

summary

  • Difference between synchronous and asynchronous
  • Event loop and message queue, that is, how to implement asynchronous mode
  • Asynchronous programming mode
  • Promise asynchronous scheme, macro task / micro task
  • Generator asynchronous scheme, async / wait syntax

Synchronous mode

  • Execute line by line
  • block

Asynchronous mode

  • Do not wait for the completion of the task, and execute the next task immediately
  • Subsequent logic is defined by callback function
  • Code confusion

Asynchronous analysis

The synchronous code is executed in document order. When encountering asynchronous code, it is first pushed into the call stack, and then directly popped up to the asynchronous api environment to continue executing the synchronous code. While executing the synchronous code, the event loop will always wait for the message to complete the asynchronous code in the column. After completion, the event loop is pushed into the call stack for execution.

Asynchronous programming callback function

It's understandable that you want to do something, and you don't know when to finish what you want to rely on. Give it to the executor of the dependent task. When the dependent task is completed, execute what you want to do.

Promise programming

Basic Usage

// Promise constructor takes a function as a parameter, and the function as a parameter has two parameters
	// The type of the resolve parameter is a function that changes the state of the object to success
		// The parameter of resolve function is the result of successful operation of asynchronous task
	// The type of the reject parameter is a function that changes the state of the object to failed
		// The parameter of reject function is the reason why the asynchronous task fails
const promise = new Promise(function(resolve,reject){
    resolve(100)
    
    // reject(new Error('promise rejected'))
})
promise.then()

promise Ajax request

// Promise AJAX

function ajax (url) {
  return new Promise(function (resolve, reject) {
    var xhr = new XMLHttpRequest()
    xhr.open('GET', url)
    // Set response type
    xhr.responseType = 'json'
    xhr.onload = function () {
      if (this.status === 200) {
        resolve(this.response)
      } else {
        reject(new Error(this.statusText))
      }
    }
    xhr.send()
  })
}

ajax('/api/urls.json').then(function (res) {
  console.log(res)
}, function (error) {
  console.log(error)
})

Promise chained call

  • The then method returns a brand new Promise
  • The return of then's resolve method is the parameter value reject of the next Promise resolve. The same is true
  • The latter then method is to register a callback for the previous Promise
  • If promise is returned in the callback, the callback of the then method will wait for its result and register the callback for the promise we returned
ajax('/api/users.json')
  .then(function (value) {
    console.log(1111)
    return ajax('/api/urls.json')
  }) // => Promise
  .then(function (value) {
    console.log(2222)
    console.log(value)
    return ajax('/api/urls.json')
  }) // => Promise
  .then(function (value) {
    console.log(3333)
    return ajax('/api/urls.json')
  }) // => Promise
  .then(function (value) {
    console.log(4444)
    return 'foo'
  }) // => Promise
  .then(function (value) {
    console.log(5555)
    console.log(value)
  })

Promise exception

  • reject is the handling of exceptions

  • The rejec in the then method can only catch the exception of the last promise

  • The exception in promise can be passed to the next promise catch method to catch the exception directly

  • Binding the unhandledrection world on the window object can catch exceptions that have not been caught manually

// It is not recommended to use it. It should be captured manually
window.addEventListener('unhandledrejection',event=>{
    const {reason,promise} = event
    console.log(reason,promise)
    // Reason = > reason for promise failure
    // Promise = > promise with exception
    event.preventDefault()
},false)
// Exception caught in node
process.on('unhandledRejection',(reason,promise)=>{
    console.log(reason,promise)
})

promise static method

  • Promise.resolve(value)
    • Create a successful method. The parameter value of the successful callback function is the value of value
    • If a Promise is returned, an exactly equal Promise object is returned
  • Promise.rejected()

promise parallel execution

Promise.all(array) combines multiple promise objects into one. If all promises succeed, the new promise will succeed. If one fails, the promise will fail. After success, the resolve callback receives an array, that is, the results returned by all promises

  • Receive an array, and each element in the array is a Promise object

promise. The rece () sub will end when it is completed

promise execution sequence

  • Macro tasks are queued again
  • Micro tasks will not be queued again and will be executed first, such as Promise, MutationObserver and process in node nextTick

Generator asynchronous scheme

Generator function

  • Executing a function does not immediately call the function and returns a generator object

Syntax:

function * foo(){
    console.log('start')
   // yield 'foo'
    
    try{
        const res = yield 'foo'
        console.log(res)
    }catch(e){
        console.log(e)
    }
    // You can capture the generator Exception thrown by throw() method
}
const generator = foo() // Returns a generator object
const result = generator.next() // Call the next() method to start the function execution and return an object
/*
	result object
	value yield Returned value
	done Indicates whether the generator has finished executing
*/
generato.throw(new Error('Generator error'))

Topics: Javascript Front-end