es6 async和await
es7 async和await ,作为genertor函数语法糖,在使用上比generator函数方便的,Generator 函数就是一个封装的异步任务,或者说是异步任务的容器。异步操作需要暂停的地方,都用yield
语句注明.
generator将异步的流程标记的很简洁,但是流程执行却并不方便,所有我们需要借助Generator的自执行下函数。Thunk 函数可以用于generator函数的自流程管理
async和await 作为generator的语法糖,自带自执行器,相对于generator具有更好的语义,yield后面只能时promise,async,await 具有更好的适用性,并不明确规定是promise,async的返回的是promise
1.asycn和await的基本使用
async如果遇到await就会等待,等待其执行结果,才会往下继续执行函数内部语句
/* 异步执行方法 */ function timeout(ms) { return new Promise((res)=>{ console.log('settimeout') setTimeout(res,ms) }) } /* await 只能在async定义的函数内部使用 */ async function asyncpriint(value,ms) { timeout(ms); console.log(value); } asyncpriint('hello world',2000); // 先输出settimeout等待2m钟输出hello world // 如果去掉await,输出settimeout并且不等待直接输出hello world
async函数返回的是一个promise
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* async返回时最终会转成一个promise */ async function donow() { return 'czklove' } async function donow2 () { return new Promise(res=>{ res('czklove') }) } async function donow3 () { return Promise.resolve('czklove') } donow().then((val)=>{ console.log(val) }) // 输出czklove donow2().then((val)=>{ console.log(val) }) // 输出czklove /* 2和3是等价的,Promise.resolve 返回一个promise */ donow3().then((val)=>{ console.log(val) }) //输出czklove // 输出输出czklove /* donow和donow2是等价的 也就是说返回值是一个值的话,他会自动转化成promise */
async返回的promise对象的状态变化
/* resolve */ async function promiseresolve(){ await Promise.resolve('czkloveresolve') return 'czklove1' } /* rejuect */ async function promisereject(){ await Promise.reject('czkloverejuct') console.log(123) return 'czklove2' } /* 内部都是resolve 一直执行下去 */ promiseresolve().then(res=>{ console.log('resolve'+res) },rej=>{ console.log('reject'+rej) }) // resolveczklove1 /* 内部其中一个await是reject,则直接返回,不会再执行下去,并且返回值是rejuect的值 */ promisereject().then(res=>{ console.log('resolve'+res) },rej=>{ console.log('reject'+rej) }) // 不会执行console.log(123) // rejectczkloverejuct
await 命令后面是一个promise对象,返回该对象的结果,如果不是promise,值直接放回该值
如果后面是一个带有then 方法的对象,那么会将其等同于promise
await 后面的promise如果执行了rejuect 则整个函数终止,并且返回该对象的结果,返回的promise对象的状态也是rejuect的
如果我们想继续执行下去,则可以将reject的promise 放入try catch 模块中,另外一种是后面跟.catch 方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 定义一个async 函数 */ async function awaitfc() { try { /* 放入try 和 catch 中 reject 不会终止函数执行 */ await Promise.reject('czklove') } catch (e){ } /* .catch 也可以使 reject 不会终止函数执行*/ await Promise.reject('czklove').catch((e)=>{ console.log(e) }) return 'jgczklove' } awaitfc().then(val=>{ console.log(val) }) //czklove async.js
函数的并发执行或继发执行
/* 定义一个async 函数 */ let i = 1; function settime(ms) { return new Promise((res)=>{ setTimeout(()=>{ res ('123'+(i++)) },ms) }) } /* 继发执行 */ async function funa() { let val1 = await settime(2000) console.log(val1) let val2 = await settime(2000) console.log(val2) let val3 = await settime(2000) console.log(val3) console.log('1111') } /* 并发执行 */ async function funa2() { let val1 = settime(2000); let val2 = settime(3000); let val3 = settime(2000); console.log(await val1) console.log(await val2) console.log(await val3) console.log(2222) } funa(); /* 继发执行 结果是顺序的 每隔2秒 输出1231 1232 1233 ,最终输出1111 */ funa2(); /* 并发 val1 val2 val3 输出结果顺序是不定的,但是可以确认,最终才输出2222 */
使用promise.all 也可以达到并发执行