async函數返回一個 Promise 對象。html
async函數內部return語句返回的值,會成爲then方法回調函數的參數。git
async function f() { return 'hello world'; } f().then(v => console.log(v)) // "hello world"
async函數內部拋出錯誤,會致使返回的 Promise 對象變爲reject狀態。拋出的錯誤對象會被catch方法回調函數接收到github
async function f() { throw new Error('出錯了'); } f().then( v => console.log(v), e => console.log(e) ) // Error: 出錯了
只有async函數內部的異步操做執行完,纔會執行then方法指定的回調函數。promise
async function getTitle(url) { let response = await fetch(url); let html = await response.text(); return html.match(/<title>([\s\S]+)<\/title>/i)[1]; } getTitle('https://tc39.github.io/ecma262/').then(console.log) // "ECMAScript 2017 Language Specification"
正常狀況下,await命令後面是一個 Promise 對象。若是不是,會被轉成一個當即resolve的 Promise 對象。異步
await命令後面的 Promise 對象若是變爲reject狀態,則reject的參數會被catch方法的回調函數接收到。async
只要一個await語句後面的 Promise 變爲reject,那麼整個async函數都會中斷執行函數
async function f() { await Promise.reject('出錯了'); await Promise.resolve('hello world'); // 不會執行 }
有時,咱們但願即便前一個異步操做失敗,也不要中斷後面的異步操做。這時能夠將第一個await放在try...catch結構裏面,這樣無論這個異步操做是否成功,第二個await都會執行。fetch
async function f() { try { await Promise.reject('出錯了'); } catch(e) { } return await Promise.resolve('hello world'); } f() .then(v => console.log(v)) // hello world
另外一種方法是await後面的 Promise 對象再跟一個catch方法,處理前面可能出現的錯誤。url
async function f() { await Promise.reject('出錯了') .catch(e => console.log(e)); return await Promise.resolve('hello world'); } f() .then(v => console.log(v)) // 出錯了 // hello world
若是await後面的異步操做出錯,那麼等同於async函數返回的 Promise 對象被reject。spa
防止出錯的方法,將其放在try...catch代碼塊之中。
async function f() { try { await new Promise(function (resolve, reject) { throw new Error('出錯了'); }); } catch(e) { } return await('hello world'); } 若是有多個await命令,能夠統一放在try...catch結構中。 async function main() { try { const val1 = await firstStep(); const val2 = await secondStep(val1); const val3 = await thirdStep(val1, val2); console.log('Final: ', val3); } catch (err) { console.error(err); } }
在 promise 以前的 await 關鍵字,使 JavaScript 等待 promise 被處理,而後: