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

/* 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 方法

/* 定義一個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 也可以達到並發執行