7
头图
"Novices of Xiaoheshan", provide front-end developers with technical information and a series of basic articles. For a better user experience, please move to our official website rookies (160c99a744ec44 https://xhs-rookies.com/ ) to learn and get the latest articles in time.

Preface

In MDN's JavaScript series, we have learned callback, promise, generator, and async/await. In this article, the author will explain the history of asynchronous development with actual examples, introduce the advantages and disadvantages of each implementation method, in order to help readers familiarize themselves with the historical process and grasp the context of asynchronous development. 异步发展历史

asynchronous

The navigation website from decades ago is refreshing and simple, with no special functions, just simple display, ready-made web pages lying quietly on the server, efficient and stress-free, people like it very much.

Today, decades later, static pages are far from meeting the needs of users. Websites have become more complex, and user interactions have become more frequent, resulting in a large number of complex internal interactions. In order to solve this complexity, various system "modes" have emerged. ", so that it is easy to obtain data externally and display it to users in real time.

Obtaining external data is actually a "network call". At this time, the term " asynchronous " appears.

Asynchronous means that two or more objects or events do not exist or happen at the same time (or multiple related things happen without waiting for the completion of the previous thing)

image-20210116210456133

Asynchronous callbacks

Asynchronous callbacks actually functions, just passed as parameters to other functions that are executed in the background. When the code running in the background ends, the callbacks function is called to notify you that the work has been completed or other interesting things have happened.

scene

let readFile = (path, callBack) => {
  setTimeout(function () {
    callBack(path)
  }, 1000)
}

readFile('first', function () {
  console.log('first readFile success')
  readFile('second', function () {
    console.log('second readFile success')
    readFile('third', function () {
      console.log('third readFile success')
      readFile('fourth', function () {
        console.log('fourth readFile success')
        readFile('fifth', function () {
          console.log('fifth readFile success')
        })
      })
    })
  })
})

advantages:

  • Solve the synchronization problem (that is, solve the problem that when a task takes a long time, the subsequent tasks are queued, which takes too long and slows down the execution of the program)

Disadvantages:

  • Callback hell (multi-level nesting) will lead to logical confusion, high coupling, and one change will lead to all changes. When nesting is too much, error handling will be complicated
  • Cannot use try...catch to catch errors
  • Can't return
  • Poor readability

Promise

A Promise object represents a value that is not necessarily known when the promise is created. It allows you to associate the final success return value or failure reason of an asynchronous operation with the corresponding handler. This allows asynchronous methods to return values like synchronous methods: asynchronous methods do not return the final value immediately, but instead return a promise so that the value can be handed over to the user at some point in the future.

scene

let readFile = (path) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (!path) {
        reject('error!!!')
      } else {
        console.log(path + ' readFile success')
        resolve()
      }
    }, 1000)
  })
}

readFile('first')
  .then(() => readFile('second'))
  .then(() => readFile('third'))
  .then(() => readFile('fourth'))
  .then(() => readFile('fifth'))

advantages:

  • After the status is changed, it will not change again, and this result can be obtained at any time
  • Asynchronous operations can be expressed in a synchronous operation process, avoiding nested callback functions
  • To a certain extent solves the readability problem of callback hell

Disadvantages:

  • Unable to cancel promise
  • When in the pending state, it is impossible to know which stage it is currently progressing to
  • The code is redundant, and the semantics will be unclear when there are a bunch of tasks

Generator

Generator function is a asynchronous programming solution provided in ES6. Syntactically, it can first be understood as, Generator function is a state machine , encapsulating multiple internal states, you need to use next() function to continue to execute the following code.

Features

  • (*) between function and function name
  • The yield expression is used inside the function body, and the function execution returns when it encounters yield

scene

var readFile = function (name, ms) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(name + '读完了')
      resolve()
    }, ms)
  })
}

var gen = function* () {
  console.log('指定generator')
  yield readFile('first', 1000)
  yield readFile('second', 2000)
  yield readFile('third', 3000)
  yield readFile('forth', 4000)
  yield readFile('fifth', 5000)
  return '完成了'
}
var g = gen()
var result = g.next()
result.value
  .then(() => {
    g.next()
  })
  .then(() => {
    g.next()
  })
  .then(() => {
    g.next()
  })
  .then(() => {
    g.next()
  })

advantages:

  • Can control the execution of the function, can be used with the co function library

Disadvantages:

  • Process management is inconvenient (that is, when to perform the first phase and when to perform the second phase)

async and await

async functions and await keywords are recently added to the JavaScript language. They are part of the JavaScript edition of ECMAScript 2017 (see ECMAScript Next support in Mozilla ). Simply put, they are syntactic sugar based on promises, making asynchronous code easier to write and read. By using them, asynchronous code looks more like old-fashioned synchronous code, so they are very worth learning.

image-20210116211018846

scene 1

var readFile = function (name, ms) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(name + '读完了')
      resolve()
    }, ms)
  })
}

async function useAsyncAwait() {
  await readFile('first', 1000)
  await readFile('second', 2000)
  await readFile('third', 3000)
  await readFile('forth', 4000)
  await readFile('fifth', 5000)
  console.log('async文件阅读完毕')
}
useAsyncAwait()

Advantages

  • Built-in actuator. Means no need to call next function or co module like generator
  • Broader applicability. Async and await are followed by promise functions, the original data type will be converted to promise
  • Semantics are clearer and concise

    Disadvantages

  • A lot of await code will block (the program will not wait in place, but continue the event loop , and continue to go down after the response) the program runs, and each await will wait for the previous one to complete

scenario 2 code in scenario 1, in fact, the second and third pseudo-requests do not actually depend on the results of first and second, but they must wait for the completion of the previous one before they can continue. What we want is for them to proceed at the same time, so The correct operation should be like this.

async function useAsyncAwait() {
  const first = readFile('first', 1000)
  const second = readFile('second', 2000)
  const third = readFile('third', 3000)
  const forth = readFile('forth', 4000)
  const fifth = readFile('fifth', 5000)
  console.log('async文件阅读完毕')

  await first
  await second
  await third
  await forth
  await fifth
}
useAsyncAwait()

Here, we store three promise objects in variables so that their associated processes can be started at the same time.

to sum up

In this article, we have introduced the usage, advantages and disadvantages of callback, promise, generator, and async/await in the history of asynchronous development of JavaScript.

Development historyadvantageDisadvantage
callbackSolved the synchronization problemCallback hell, poor readability, unable to try/catch, unable to return
promiseTo a certain extent solves the readability of callback hellUnable to cancel, when there are many tasks, there is also unclear semantics
generatorCan control the execution of the function, can be used with the co function libraryProcess management is inconvenient (i.e. when to perform the first phase and when to perform the second phase
async/awaitSemantics are clearer and concise, with built-in actuator cognition may cause a lot of await blocking (the program does not wait in place, but continues the 160c99a744f3ac event loop , wait until the response and continue to go down)

Among the existing asynchronous solutions, async/await is the most used. The biggest advantage it brings us is the style of synchronous code, concise and clear semantics.

related articles


小和山的菜鸟们
377 声望2.1k 粉丝

每日进步的菜鸟,分享前端学习手册,和有心学习前端技术的小伙伴们互相探讨,一同成长。