async異步
async
函數返回一個 Promise 對象,能夠使用then
方法添加回調函數。當函數執行的時候,一旦遇到await
就會先返回,等到異步操做完成,再接着執行函數體內後面的語句。async
function setNumAdd(n) { return new Promise((resolve,reject) =>{ setTimeout( ()=>{ n +=1; resolve(n) },1000) }) } function setNumSub(n) { return new Promise((resolve,reject) =>{ setTimeout( ()=>{ n -=1; resolve(n) },1000) }) } async function d(n) { const w1 = await setNumAdd(n); const w2 = await setNumSub(n); return w1+w2 } d(10).then( v=>{ console.log(v) //10 })
async
函數返回一個 Promise 對象。async
函數內部return
語句返回的值,會成爲then
方法回調函數的參數。函數
async function f() { return 'hello world'; } f().then(v => console.log(v)) // "hello world"
async
函數內部拋出錯誤,會致使返回的 Promise 對象變爲reject
狀態。拋出的錯誤對象會被catch
方法回調函數接收到。spa
async function f() { throw new Error('出錯了'); } f().then( v => console.log(v), e => console.log(e) ) //等同於 f().then( v=> console.log(v)).catch( e=>console.log(e)) // Error: 出錯了
awaitcode
正常狀況下,await
命令後面是一個 Promise 對象,返回該對象的結果。若是不是 Promise 對象,就直接返回對應的值。對象
async function f() { // 等同於 // return 123; return await 123; } f().then(v => console.log(v)) // 123
任何一個await
語句後面的 Promise 對象變爲reject
狀態,那麼整個async
函數都會中斷執行。blog
async function f() { await Promise.reject('出錯了'); await Promise.resolve('hello world'); // 不會執行 }
上面代碼中,第二個await
語句是不會執行的,由於第一個await
語句狀態變成了reject
。get
有時,咱們但願即便前一個異步操做失敗,也不要中斷後面的異步操做。這時能夠將第一個await
放在try...catch
結構裏面,這樣無論這個異步操做是否成功,第二個await
都會執行。回調函數
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
方法,處理前面可能出現的錯誤it
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
命令,能夠統一放在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); } }
let foo = await getFoo();
let bar = await getBar();
多個await
命令後面的異步操做,若是不存在繼發關係,最好讓它們同時觸發。
上面代碼中,getFoo
和getBar
是兩個獨立的異步操做(即互不依賴),被寫成繼發關係。這樣比較耗時,由於只有getFoo
完成之後,纔會執行getBar
,徹底能夠讓它們同時觸發。
// 寫法一 let [foo, bar] = await Promise.all([getFoo(), getBar()]); // 寫法二 let fooPromise = getFoo(); let barPromise = getBar(); let foo = await fooPromise; let bar = await barPromise;