Skip to content

为什么会有async await 语法?

ES6 Promise

ES6新增了Promise特性。它的出现是为了更好地解决JavaScript中异步编程的问题,传统的异步编程最大的特点就是地狱般的回调嵌套,一旦嵌套次数过多,就很容易使我们的代码难以理解和维护。 而Promise则可以让我们通过链式调用的方法去解决回调嵌套的问题,使我们的代码更容易理解和维护,而且Promise还增加了许多有用的特性,让我们处理异步编程得心应手。

ES6 生成器(Generator)

ES6定义的生成器函数有别于普通的函数,生成器可以在执行当中暂停自身,可以立即恢复执行也可以过一段时间之后恢复执行。

最大的区别就是它并不像普通函数那样保证运行到完毕。还有一点就是,在执行当中每次暂停或恢复循环都提供了一个双向信息传递的机会,生成器可以返回一个值,恢复它的控制代码也可发回一个值。

生成器函数、生成器

function* generator(arr) {
    yield arr[0]
    yield arr[1]
    yield arr[2]
    return "success"
}

var gen = generator([1, 2, 3])
console.log(gen)
console.log(gen.next())
console.log(gen.next())
console.log(gen.next())
console.log(gen.next())
function* generator(arr) {
    yield arr[0]
    yield arr[1]
    yield arr[2]
    return "success"
}

var gen = generator([1, 2, 3])
console.log(gen)
console.log(gen.next())
console.log(gen.next())
console.log(gen.next())
console.log(gen.next())

如上代码如果yield返回的是值、或对象调用看起来还OK。

  function* generator() {
    var res = yield new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(1)
      }, 1000)
    })
    res = yield new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(res + 2)
      }, 1000)
    })
    res = yield new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(res + 3)
      }, 1000)
    })
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("success" + res)
      }, 1000)
    })
  }

  var gen = generator()
  console.log("gen:", gen)
  var value1 = gen.next()
  console.log(value1)
  value1.value.then((value) => {
    console.log('Promise1 value:', value)

    gen.next(value).value.then((value) => {
      console.log('Promise2 value:', value)

      gen.next(value).value.then((value) => {
        console.log('Promise3 value:', value)

        gen.next(value).value.then((value) => {
          console.log('Promise4 value:', value)

        })
      })
    })
  })
  function* generator() {
    var res = yield new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(1)
      }, 1000)
    })
    res = yield new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(res + 2)
      }, 1000)
    })
    res = yield new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(res + 3)
      }, 1000)
    })
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("success" + res)
      }, 1000)
    })
  }

  var gen = generator()
  console.log("gen:", gen)
  var value1 = gen.next()
  console.log(value1)
  value1.value.then((value) => {
    console.log('Promise1 value:', value)

    gen.next(value).value.then((value) => {
      console.log('Promise2 value:', value)

      gen.next(value).value.then((value) => {
        console.log('Promise3 value:', value)

        gen.next(value).value.then((value) => {
          console.log('Promise4 value:', value)

        })
      })
    })
  })

如上代码如果yield返回的是Promise 就会出现回调地狱的问题。

ES7 async await

async await 语法的出现就是为了解决这种回调地狱的问题。

总结

  • 首先 async/await 是一种用于处理异步操作的语法糖,在ES2017中被引入,用于更简洁地编写基于Promise的链式回调代码。
  • 使用 async/await 主要是避免了传统的回调函数或 Promise 链的嵌套。

参考

https://juejin.cn/post/7281535380590559243?searchId=202310310948531CA24C843535DA63EB62