ES7带来了async和await,让js的异步编程更加方便。
1、async 做一件什么事情
一句话概括: 带 async 关键字的函数,它使得你的函数的返回值必定是 promise 对象
也就是
如果async关键字函数返回的不是promise,会自动用Promise.resolve()包装
如果async关键字函数显式地返回promise,那就以你返回的promise为准
这是一个简单的例子,可以看到 async 关键字函数和普通函数的返回值的区别
async function fn1(){ return 1 } function fn2(){ return 1 } console.log(fn1()) console.log(fn2()) fn1().then(function(res){ console.log(res) }) // Promise { 1 } // 1 // 1
所以你看,async 函数也没啥了不起的,以后看到带有 async 关键字的函数也不用慌张,你就想它无非就是把return值包装了一下,其他就跟普通函数一样。
关于async关键字还有那些要注意的?
在语义上要理解,async表示函数内部有异步操作
另外注意,一般 await 关键字要在 async 关键字函数的内部,await 写在外面会报错。
2.await 在等什么?
一句话概括: await等的是右侧「表达式」的结果
也就是说,
右侧如果是函数,那么函数的return值就是「表达式的结果」
右侧如果是一个 ‘hello’ 或者什么值,那表达式的结果就是 ‘hello’
3.await 等到之后,做了一件什么事情?
那么右侧表达式的结果,就是await要等的东西。
等到之后,对于await来说,分2个情况
- 不是promise对象
- 是promise对象
如果不是 promise , await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,把这个非promise的东西,作为 await表达式的结果
如果它等到的是一个 promise 对象,await 也会暂停async后面的代码,先执行async外面的同步代码,等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果。
4.为什么使用Promise
通过Promise
,可以将一步操作以同步操作的流程表达出来,可以避免层层嵌套的回调函数(回调地域),并且Promise
提供了统一的接口,使得控制异步操作更加容易
function sleep(second){ return new Promise((resolve,reject) => { setTimeout(() => { let res=Math.random() if(res<0.5){ resolve('<0.5') }else{ reject('>0.5') } },second); }) } function test(){ return 'test'; } function test2(){ return 'test2'; } async function open(){ await sleep(2000).then((res)=>{ console.log(res) }).catch((e)=>{ console.log(e) }) console.log('open') let res=await test() console.log(res) } async function open2(){ let res=await test2() console.log(res) } open() console.log('外面的') open2() //输入顺序 // 外面的 // test2 // <0.5 // open // test