如何在 JavaScript 异步编程中使用 ES8 async await?

在现代的 Web 开发中,前端开发人员不再只是关注 HTML、CSS 和 JavaScript 语言本身,他们还需要关注许多框架和库以及如何处理异步编程。

JavaScript 这种单线程语言使得异步编程非常重要,因为阻止主线程的操作会导致页面冻结或崩溃。但是,在过去,一些 JavaScript 软件开发中常使用回调和 Promise 形式的异步编程,这些方法比较繁琐和难以管理。

ES8 的 async/await 语法为 JavaScript 异步编程提供了一个更直接、更易于管理的方式。本文将详细地介绍如何在 JavaScript 异步编程中使用 ES8 async/await,并附带实际的代码示例。

async 和 await

ES6 引入了 Promise,许多开发人员开始采用 Promise 进行异步编程。 Promise 提供了一种解决回调 hell 的方式,这使得代码更简单、更易于理解。

然而,Promise 在处理嵌套 Promise 时,仍然很难理解。而且,Promise 还需要使用 .then() 和 .catch() 方法以处理 Promise 返回的数据,这可能会使代码变得复杂冗长。

ES8 引入了 async/await 它的作用就是用同步的形式实现异步编程,async/await 将 Promise 更加用户友好和便于组织。

async 和 await 是一种处理 Promise 的方式。async 关键字可以放在函数前面,使得函数总是返回一个 Promise。await 关键字可以放在 Promise 调用后面,暂停代码执行,直到 Promise 完成并返回结果。

使用 async 和 await

async 和 await 可以帮助我们避免回调地狱,代码更简洁、易于管理。我们来看一下 async 和 await 的用法。

一个修改后的异步回调例子

function fetchData() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('Hello, World!')
    }, 1000)
  })
}

现在我们将使用 async 和 await,以同步方式修改代码。

async:让函数顺序执行, 返回内容包装成一个promise 对象;

await:等到异步部分执行完毕,将返回值返回出来;如果返回的对象是一个promise 对象,则等待该promise 对象执行完毕。

async function fetchData() {
  const result = await new Promise(resolve => {
    setTimeout(() => {
      resolve('Hello, World!')
    }, 1000)
  })

  console.log(result)
}
fetchData()

在这个示例中,我们使用 async 函数 fetchData(),将 Promise 转换为更直观、易于理解的形式。我们使用 await 关键字等待 Promise 在 1 秒后返回结果。该函数的返回值始终是一个 Promise 对象,即使我们没有明确返回任何内容。

这种形式看起来更直观整洁,提高了代码可读性。

我们再来看一个稍微复杂一点的异步嵌套例子:

function fetchData() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('Success')
    }, 1000)
  })
}

function fetchDataWrapper() {
  return new Promise(resolve => {
    setTimeout(async () => {
      try {
        const response = await fetchData()
        console.log(response)
        resolve('Done')
      } catch (error) {
        console.error(error)
      }
    }, 2000)
  })
}

fetchDataWrapper()

这个例子中,我们将 fetchData() 封装在 fetchDataWrapper() 中。fetchDataWrapper() 返回一个 Promise,并在两秒后输出 fetchData() 返回的结果。如果 fetchData() 返回错误,我们会抛出错误。

虽然表面上看起来不错,但它的嵌套层数越来越深。使用 async/await 让让这个例子更易于理解:

async function fetchDataWrapper() {
  try {
    const response = await fetchData()
    console.log(response)
    return 'Done'
  } catch (error) {
    console.error(error)
  }
}

fetchDataWrapper()

fetchDataWrapper() 中的所有异步部分现在都在一个 try/catch 块中。这种深度嵌套的异步函数,变得更加直观可读了。

总结

async 和 await 已成为 JavaScript 异步编程的标准做法。它们可以帮助我们让异步代码更易于理解和管理。

我们可以用它们来简化代码并避免回调嵌套带来的混乱。

相比其他异步方式,async/await 更容易实现数据依赖、错误处理、代码维护等。

在 ES8 及以上的版本中,我们完全可以放心大胆的采用 async/await 这种更加简单明了的异步编程方式。

示例代码

下面是一个完整的示例代码:

async function getData() {
  const data = await fetch('https://jsonplaceholder.typicode.com/todos/1')
  const jsonData = await data.json()
  console.log(jsonData)
}

getData()

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65add4e4add4f0e0ff74d634