大家還記得好久好久以前講過Generator function嗎?
忘記的可以來複習一下超突然決定來介紹Generator function吧
對於同步和非同步,最常見的說法是「同步模式下,每個任務必須按照順序執行,後面的任務必須等待前面的任務執行完成,非同步模式則相反,後面的任務不用等前面的,各自執行各自的任務」,不過我目前看下來,同步的的意思比較像按順序一行行執行,非同步則會先將一些事件加入執行佇列。
就像這邊的範例
非同步
console.log('開始');
setTimeout(() => {
console.log('非同步事件');
}, 0);
console.log('程式碼結束');
結果如下,並不會按照順序出現 console.log
ES6 出現了 promise,ES7 出現了 async、await,幫助我們可以更容易的進行程式邏輯的撰寫。
同步
function promiseFn(num, time = 500) {
return new Promise((resolve, reject) => {
setTimeout(() => {
num ? resolve(`${num}, 成功`) : reject("失敗");
}, time);
});
}
// 同步方法執行
promiseFn(1)
.then((res) => {
console.log(res); // 1, 成功
setTimeout(() => {
console.log("setTimeout");
}, 500);
return promiseFn(2); // 鏈接第二次的 Promise 方法
})
.then((res) => {
console.log(res); // 2, 成功
});
結果如下,按照順序出現 console.log
async function
用來定義一個非同步函式,不過其內部以“同步的方式運行非同步”程式碼。await
則是暫停非同步函式的運行,直到非同步回傳值( resolve
或 reject
)後再繼續非同步函式的運行。這裡不就跟 Generator function 裡的 yield 看起來一模模一樣樣嗎
不過 async 比起不在 saga 中的 Generator function 看起來可好用多了。
在 promise 時會需要使用 then() 來執行
在 Generator function 時會需要 next()
Async / Await 目的是讓程式碼的結構變得更加簡潔、易懂,實際操作的時候看起來也真的比較單純。
那我們下方就來認識一下 Async / Await的用法吧,會與上方 promiseFn 一同使用
async function getData() {
const data1 = await promiseFn(3); // 因為 await,promise 函式被中止直到回傳
// console.log(data1);
const data2 = await promiseFn(4);
console.log(data1, data2); // 1, 成功 2, 成功
}
getData();
await 跟 yield 相同,會先得到右方回傳值才執行下一個 await,所以當 data1 的await fail 時,後續 await 也不會執行了,這邊我們依樣可以使用 try catch 來執行遇到錯誤的的後續操作。
async function getData2() {
try {
const data1 = await promiseFn(3);
const data2 = await promiseFn(4);
console.log(data1, data2); // 1, 成功 2, 成功
} catch (err) {
console.log("error", err);
}
}