async&await
什么是async和await?
-
async
MDN:
async function 用来定义一个返回
AsyncFunction
对象的异步函数。异步函数是指通过事件循环异步执行的函数,它会通过一个隐式的Promise
返回其结果。如果你在代码中使用了异步函数,就会发现它的语法和结构会更像是标准的同步函数。简单来说,async函数就是用于将异步的Promise转换成类似同步函数的形式。
-
await
async函数中的关键字。await值能在async函数中使用。
await后面必须接一个接一个返回了 Promise的函数的调用形式(实际上是await + Promise) 。
使用async和await
示例代码:
function random(){
return new Promise((resolve)=>{
setTimeout(()=>{
let n = parseInt(Math.random() * 6 + 1 , 10 )
let b = 0
resolve({n,b})
},3000)
})
}
async function specialFn(){
let result = await random()
console.log(result)
}
specialFn() // {a:[1~6],b:0}
console.log(specialFn()) // Promise
上面 specialFn
的内部,执行顺序实际上是 先执行 await random()
,等待random()返回结果后,赋值给 n ;接着才继续往下执行。
如果没有 await, 它并不会等待 random() 结束后才会继续执行,而是直接往下执行。 在上面的例子中,如果我们删去await,specialFn()
中console.log(result)
结果就是 Promise对象,而不是resolve传递过来的结果。
async 函数返回的是一个 Promise,所以async await实际上就是Promise的语法糖,让Promise变得更“同步”更好理解。
由于 async function 是异步的,所以上面的代码中,我们会先执行console.log(specialFn())
,然后才执行2个specialFn()
。
async中获取结果与错误信息
function guessNum(largeORsmall){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
let n = parseInt(Math.random() * 6 + 1 , 10 )
if(n>3){
if(largeORsmall==='large'){
resolve(n)
}else{
reject(n)
}
}else{
if(largeORsmall==='small'){
resolve(n)
}else{
reject(n)
}
}
},3000)
})
}
async function specialFn(){
try{
let result = await guessNum('large')
console.log(`'bingo the number is' ${result}`)
}catch(error){
console.log(`'sorry the number is' ${error}`)
}
}
specialFn()
console.log(specialFn())
在Promise中,我们可以通过,resolve和reject的第一个参数来传递需要的内容。比如,例子中我们传递的就是随机数n。如果需要传递多个变量,可以通过对象的形式。
在async函数中,获取resolve传递的内容很简单,let result = await guessNum('large')
result获取的就是resolve传递的内容。
而获取reject传递过来的‘错误信息’则需要通过catch
。
多个Promise怎么解决?
如果直接使用Promise 我们可以通过 all race 的API来解决那么await呢?
首先明确的是,await后面只能接一个Promise
如果 await后面要接多个Promise也需要借助 all race的帮助
async和await的意义
这种方式比起Promise的then更加复杂,为什么要是使用async await 呢?因为对同步的追求。
Promise.then(f1,f2)的形式,对逻辑不太友好,我们并不清楚f1 f2 何时执行。但是async await的形式就非常清晰,我们通过这种方式,把异步函数,转换成可以用类似于同步函数的形式,使得代码阅读起来更加顺畅。