async函數的使用方式,直接在普通函數前面加上async,表示這是一個異步函數,在要異步執行的語句前面加上await,表示後面的表達式須要等待。async是Generator的語法糖,相比較Generator函數在如下四方面作了改進es6
Generator函數是須要調用next指令來運行異步的語句,async不須要調用next,直接像運行正常的函數那樣運行就能夠promise
語義化更明確,相比較於Generator的*和yield,async和await更明確。異步
yield命令後面只能是 Thunk 函數或 Promise 對象,而async函數的await命令後面,能夠是Promise 對象和原始類型的值(數值、字符串和布爾值,但這時等同於同步操做)。async
async直接返回一個promise對象,能夠用then和cache來處理。函數
async function getStockPriceByName(name) { let symbol = await getStockSymbol(name); let price = await getPriceByName(symbol); return price } getStockPriceByName('goog').then( (result)=> { console.log(result); }).catch((err)=>{ console.log(err) })
上面的async異步函數遇到await會先返回一個Promise對象,等到異步操做執行完畢,纔會根據結果來執行具體的回調函數。spa
函數聲明code
async function foo() {}
表達式聲明對象
var bar = async function () {}
對象聲明遞歸
var obj = { async bazfunction(){ } }
箭頭函數聲明字符串
var fot = async() => { }
await後面是一個promise對象,若是不是,會轉成一個resolve的promise對象
async function f() { return await 123; } f().then(function (a) { console.log(a); })
await後面的promise對象,若是reject,則reject參數會被cache參數接收到,寫不寫return均可以,而且reject下面的代碼不會執行,若是想下面的代碼執行,必須用try cache包住
async function a() { try{ await Promise.reject('出錯了!') }catch (e){ return await Promise.resolve('請從新填寫') } } a().then(function () { console.log(err); }).catch(function (err) { console.log(err); })
上面的代碼若是不用try cache包裹reject,則下面的代碼不會執行,而且reject語句是不用return返回的,resolve語句是須要用return返回;
若是await後面的異步操做出錯,那麼等同於async函數返回的 Promise 對象被reject。因此一般的處理方法有兩種
用try catch包住可能會出錯的部分
async function myFunction() { try { await somethingThatReturnsAPromise(); } catch (err) { console.log(err); } }
另外一種寫法是對可能要出錯的異步操做添加catch回調函數
async function myFunction() { await somethingThatReturnsAPromise().catch((err)=> { console.log(err); }) }
let a=await getFoo(); let b=await getBar();
上面的兩個方法都是異步操做,不存在依賴關係,因此咱們能夠同時觸發,改寫成下面的
//第一種寫法 let [a,b]=Promise.all([getFoo(),getBar()]) //第二種寫法 let aPromise=getFoo(); let bPromise=getBar(); let a=await aPromise; let b=await bPromise;
async函數就是將執行器和Generator作爲一個函數返回。
async function fn(){} //等同於 function fn() { return spawn(function* () { }) }
function spawn(genF) { /**** * 返回的是一個promise */ return new Promise(function(resolve, reject) { var gen=genF(); //運行Generator這個方法; /*** * 執行下一步的方法 * @param fn 一個調用Generator方法的next方法 */ function step(fn) { //若是有錯誤,則直接返回,不執行下面的await try { var next=fn(); }catch (e){ return reject(e) } //若是下面沒有yield語句,即Generator的done是true if(next.done){ return resolve(next.value); } // 若是下面還有yield語句,resolve繼續執行遞歸執行gen.next(),reject則拋出錯誤 Promise.resolve(next.value).then((val)=>{ step(function(){ return gen.next(val) } ) }).catch((e)=>{ step(function(){ return gen.throw(e) } ) }) } step(function () { return gen.next(); }) }); }
參考阮大神的文章:http://es6.ruanyifeng.com/#do...