请选择 进入手机版 | 继续访问电脑版

具有Async和Await的现代异步JavaScript

前端开发  / Javascript  / 倒序浏览   © 著作权归作者本人所有

#楼主# 2020-5-17

跳转到指定楼层

探索JavaScript中异步函数的现代方法。JavaScript从回调到Promises的发展时间很短,而且由于ES2017异步JavaScript使用async / await语法甚至更简单

为什么引入异步/等待?

它们减少了兑现Promise的样板,并减少了兑现Promise的“不破坏链条”限制。

在ES2015中引入Promises时,它们旨在解决异步代码的问题,但确实做到了,但是在将ES2015和ES2017分开的两年中,很明显,诺言不可能成为最终的解决方案

引入了Promise来解决著名的回调地狱问题,但是它们自己引入了复杂性以及语法复杂性。

它们是很好的原语,可以向开发人员公开更好的语法,因此,当时间合适时,我们可以获得异步函数

它们使代码看起来像是同步的,但它是异步的并且在后台无阻塞。

怎么运行的

异步函数返回一个Promise,例如以下示例:

const doSomethingAsync = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve('I did something'), 3000)
  })
}

当您要调用此函数时await将在其前面,并且调用代码将停止,直到Promise被解决或被拒绝。一个警告:客户端函数必须定义为async。这是一个例子:

const doSomething = async () => {
  console.log(await doSomethingAsync())
}

一个简单的例子

这是用于异步运行函数的async / await的简单示例:

const doSomethingAsync = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve('I did something'), 3000)
  })
}

const doSomething = async () => {
  console.log(await doSomethingAsync())
}

console.log('Before')
doSomething()
console.log('After')

上面的代码会将以下内容打印到浏览器控制台:

Before
After
I did something //after 3s

Promise一切

async任何函数之前加关键字意味着函数将返回一个promise。

即使没有明确地这样做,它也会在内部使它返回Promise。

这就是为什么此代码有效的原因:

const aFunction = async () => {
  return 'test'
}

aFunction().then(alert) // This will alert 'test'

它与:

const aFunction = async () => {
  return Promise.resolve('test')
}

aFunction().then(alert) // This will alert 'test'

该代码更容易阅读

如您在上面的示例中看到的,我们的代码看起来非常简单。将其与使用普通Promise以及链接和回调函数的代码进行比较。

这是一个非常简单的示例,当代码复杂得多时,将会带来主要的好处。

例如,这是您如何使用promises获取并解析JSON资源的方法:

const getFirstUserData = () => {
  return fetch('/users.json') // get users list
    .then(response => response.json()) // parse JSON
    .then(users => users[0]) // pick first user
    .then(user => fetch(`/users/${user.name}`)) // get user data
    .then(userResponse => userResponse.json()) // parse JSON
}

getFirstUserData()

这是使用await / async提供的相同功能:

const getFirstUserData = async () => {
  const response = await fetch('/users.json') // get users list
  const users = await response.json() // parse JSON
  const user = users[0] // pick first user
  const userResponse = await fetch(`/users/${user.name}`) // get user data
  const userData = await userResponse.json() // parse JSON
  return userData
}

getFirstUserData()

多个异步功能串联

异步函数可以很容易地链接起来,并且语法比普通的诺言更具可读性:

const promiseToDoSomething = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve('I did something'), 10000)
  })
}

const watchOverSomeoneDoingSomething = async () => {
  const something = await promiseToDoSomething()
  return something + ' and I watched'
}

const watchOverSomeoneWatchingSomeoneDoingSomething = async () => {
  const something = await watchOverSomeoneDoingSomething()
  return something + ' and I watched as well'
}

watchOverSomeoneWatchingSomeoneDoingSomething().then(res => {
  console.log(res)
})

将打印:

I did something and I watched and I watched as well

更容易调试

调试Promise很难,因为调试器不会跳过异步代码。

异步/等待使这非常容易,因为对于编译器而言,它就像同步代码一样。、、

转播转播
回复

使用道具

成为第一个评论人

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于作者

damonare

网站编辑

  • 主题

    267

  • 帖子

    269

  • 关注者

    0

手机版|ObjectX 超对象 |粤ICP备20005929号
Powered by  © 2019-2020版权归ObjectX 超对象