异步的JavaScript
从未如何简单!过去段时间,咱们使用回调。而后,咱们使用promises
。如今,咱们有了异步功能函数。javascript
异步函数可以使得(咱们)编写异步JavaScript更加容易,可是,它自带一套陷阱,对初学者很不友好。java
在这个由两部分组成的文章中,我想分享下你须要了解的有关异步函数的内容。【PS:另外一部分暂不打算翻译】git
异步功能函数包含async
关键词。你能够在正常的函数声明中使用它:github
async function functionName (arguments) {
// Do something asynchronous
}
复制代码
你也能够使用箭头函数。数组
const functionName = async (arguments) => {
// Do something asynchronous
}
复制代码
(异步函数)它无论你返回什么。其返回值都是promise
。promise
const getOne = async _ => {
return 1
}
const promise = getOne()
console.log(promise) // Promise
复制代码
笔记:在接着往前读以前,你应该知道什么是JavaScript Promises知识点,以及如何使用它们。不然,它会开始变得混乱。这篇文章会帮助你熟悉JavaScript Promise。异步
当你调用promise
时,你会在then
中处理下一步,以下:async
const getOne = async _ => {
return 1
}
getOne()
.then(value => {
console.log(value) // 1
})
复制代码
await
关键字容许你等待promise去解析。一旦解析完promise,它就会返回参数传递给then
调用。函数
const test = async _ => {
const one = await getOne()
console.log(one) // 1
}
test()
复制代码
在返回承诺(promise)以前没有必要等待(await)。你能够直接退回承诺。post
若是你
return await
些内容,则你首先是解决了原先promise。而后,你从已经解析的内容(resolved value)建立新的promise。return await
真的没作什么有效的东西。无需额外的步骤。
// Don't need to do this
const test = async _ => {
return await getOne()
}
test()
.then(value => {
console.log(value) // 1
})
复制代码
// Do this instead
const test = async _ => {
return getOne()
}
test()
.then(value => {
console.log(value) // 1
})
复制代码
注意:若是你不须要
await
,则不须要使用异步功能(async function)。上面的例子能够改写以下:
// Do this instead
const test = _ => {
return getOne()
}
test()
.then(value => {
console.log(value) // 1
})
复制代码
若是一个promise出错了,你能够使用catch调用来处理它,以下所示:
const getOne = async (success = true) => {
if (success) return 1
throw new Error('Failure!')
}
getOne(false)
.catch(error => console.log(error)) // Failure!
复制代码
若是你想在一个异步函数中处理错误,你须要调用try/catch
。
const test = async _ => {
try {
const one = await getOne(false)
} catch (error) {
console.log(error) // Failure!
}
}
test()
复制代码
若是你有多个await
关键字,错误处理可能变得很难看...
const test = async _ => {
try {
const one = await getOne(false)
} catch (error) {
console.log(error) // Failure!
}
try {
const two = await getTwo(false)
} catch (error) {
console.log(error) // Failure!
}
try {
const three = await getThree(false)
} catch (error) {
console.log(error) // Failure!
}
}
test()
复制代码
还有更好的方法。
咱们知道异步函数老是返回一个promise。当咱们调用promise时,咱们能够在catch
调用中处理错误。这意味着咱们能够经过添加.catch
来处理异步函数中的任何错误。
const test = async _ => {
const one = await getOne(false)
const two = await getTwo(false)
const three = await getThree(false)
}
test()
.catch(error => console.log(error)))
复制代码
注意:Promise的
catch
方法只容许你捕获一个错误。
await
阻止JavaScript执行下一行代码,直到promise解析为止。这可能会致使代码执行速度减慢的意外效果。
为了实际演示这点,咱们须要在解析promise以前建立一个延迟。咱们能够使用sleep
功能来建立延迟。
const sleep = ms => {
return new Promise(resolve => setTimeout(resolve, ms))
}
复制代码
ms
是解析前等待的毫秒数。若是你传入1000
到sleep
函数,JavaScript将等待一秒才能解析promise。
// Using Sleep
console.log('Now')
sleep(1000)
.then(v => {
console.log('After one second')
})
复制代码
假设getOne
须要一秒来解析。为了建立这个延迟,咱们将1000
(一秒)传入到sleep
。一秒事后,sleep
promise解析后,咱们返回值1。
const getOne = _ => {
return sleep(1000).then(v => 1)
}
复制代码
若是你使用await getOne()
,你会发如今getOne
解析以前须要一秒钟。
const test = async _ => {
console.log('Now')
const one = await getOne()
console.log(one)
}
test()
复制代码
如今,假设你须要处理三个promises。每一个promise都有一秒钟的延迟。
const getOne = _ => {
return sleep(1000).then(v => 1)
}
const getTwo = _ => {
return sleep(1000).then(v => 2)
}
const getThree = _ => {
return sleep(1000).then(v => 3)
}
复制代码
若是你连续await
这三个promises,你将要等待三秒才能解析完全部promises。这并很差,由于咱们强迫JavaScript在作咱们须要作的事情以前等待了两秒钟。
const test = async _ => {
const one = await getOne()
console.log(one)
const two = await getTwo()
console.log(two)
const three = await getThree()
console.log(three)
console.log('Done')
}
test()
复制代码
若是getOne
,getTwo
和getThree
能够同时获取,你将节省两秒钟。你能够使用Promise.all
同时获取这三个promises。
有三个步骤:
Promise.all
来await
promises数组以下所示:
const test = async _ => {
const promises = [getOne(), getTwo(), getThree()]
console.log('Now')
const [one, two, three] = await Promise.all(promises)
console.log(one)
console.log(two)
console.log(three)
console.log('Done')
}
test()
复制代码
这就是你须要了解的基本异步功能函数!我但愿这篇文章为你扫除了些障碍。
笔记:这篇文章是Learn JavaScript的修改摘录。若是你发现本文有用,你可能须要去查看它。
至此,系列文callbacks,promises和async/await共三篇文章已经完成~