之前曾經寫過一篇 promise 的文章,知道運用 promise 可避免 callback hell 的發生。 es7 的 async/await 其實是 promise 語法糖,讓你可以用更簡潔的方法達到非同步。之前看到許多 async/awit 文章都還是先寫一個 promise,其實是不需要的, 因為 async function 本身就會回傳 promise, (async 就是 promise 語法糖阿,當然就是不用重覆寫了),以下會詳細說明要如何用 async 寫法取代 promise
若我想要 a 做完再做 b, 用 promise 跟 async 可以達到相同結果。可以看出 async 更直覺一點
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// Promise function run(para) { return new Promise((resolve, reject) => { resolve(para + para) }) } run(2) .then(a => run(a)) .then(b => run(b)) //16 // async // 可以用 es6 arrow function 更簡化 // async run = () => {} async function run (para) { return para + para; } (async () => { let a = await run(2) let b = await run(a) let c = await run(b) return c; })() //16 |
下面兩個會得到一樣的結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// promise async function f() { return Promise.resolve(1); } f().then(alert); // 1 // async async function f() { return 1; } f() // // will return a promise .then(alert); // 1 |
Awiat 只能包在 async function 裡,Awiat 只能包在 async function 裡,Awiat 只能包在 async function 裡. 很重要所以說三次。所以 await 也無法寫在一般 function 裡喔
關鍵字 Awiat 告訴 js 要等待 promise 做完再輪到你。像跑接力賽一樣
1 2 3 4 5 6 7 8 9 10 11 12 |
async function f() { let promise = new Promise((resolve, reject) => { setTimeout(() => resolve("done!"), 1000) }); let result = await promise; // wait till the promise resolves (*) alert(result); // "done!" } f(); |
會過一秒等待 promise 做完,再 alert()。在這一秒之間程式碼可以同時做別的事情不會就此就打住 (這就是非同步的好處阿)。
1 2 3 4 5 6 7 8 9 |
async function run(para) { return para + 1; } async function result(){ let a = await Promise.all([run(1), run(2)]); return a; } result(); // [2, 3] |
Promise.all 裡面東西他會同時做,不會等第一個做完才做第二個。像跑馬拉松一樣大家一起出發
需要寫 try catch 才能知道
1 2 3 4 5 6 7 8 9 10 11 12 13 |
async function f() { try { // 成功就成功 let response = await fetch('/no-user-here'); let user = await response.json(); } catch(err) { // 失敗就在這 // catches errors both in fetch and response.json alert(err); } } f(); |
或是這樣寫
1 2 3 4 5 6 |
async function f() { let response = await fetch('http://no-such-url'); } // f() becomes a rejected promise f().catch(alert); // TypeError: failed to fetch // (*) |