深入淺出JS中的非同步程式設計(ES6 VS ES8)
阿新 • • 發佈:2020-07-31
介紹下為什麼有非同步程式設計以及JavaScript中是如何來寫非同步程式碼的:
通常在Web開發中,我們需要處理非同步操作-在繼續執行其他任務時可以等待的操作。我們向網路,資料庫或任何數量的類似操作發出請求。JavaScript是非阻塞性的:JavaScript不會在等待時停止執行程式碼,而是使用事件迴圈,讓它可以在等待這些非同步操作完成時有效地執行其他任務。
最初,JavaScript使用回撥函式來處理非同步操作。回撥的問題在於它們鼓勵複雜的巢狀程式碼,這些程式碼很快變得難以閱讀,除錯和擴充套件。藉助ES6,JavaScript集成了Promise,使我們能夠編寫出更具可讀性的程式碼。JavaScript正在不斷改進,並且 ES8提供了一種新語法來處理我們的非同步操作async...await
。該async...await
語法使我們能夠編寫非同步程式碼,該程式碼的讀取方式與傳統的同步程式類似。注意它並沒有提供什麼新的功能。
1.Promise是什麼?Promises are objects that represent the eventual outcome of an asynchronous operation。這是官方概念。
下面給上程式碼給出使用Promise的思路 :
const executorFunction = (resolve, reject) => {
if (someCondition) {
resolve( 'I resolved!');
} else {
reject('I rejected!');
}
}
// 1. 建立一個Promise物件,需要傳入一個執行函式executorFunction。當Promise的建構函式被執行時,該函式也會被執行。
// 2. executorFunction包括了兩個引數 resolve reject, 這兩個引數也是函式 由JavaScript自己提供。
const myFirstPromise = new Promise(executorFunction);
處理完後的非同步結果用then和catch:
prom .then((resolvedValue)=> { console.log(resolvedValue); }) .catch((rejectionReason) => { console.log(rejectionReason); });
鏈式使用promise(處理的非同步操作有順序):
firstPromiseFunction() .then((firstResolveVal) => { return secondPromiseFunction(firstResolveVal); }) .then((secondResolveVal) => { console.log(secondResolveVal); });
併發使用promise(處理的非同步操作沒有順序):
let myPromises = Promise.all([returnsPromOne(), returnsPromTwo(), returnsPromThree()]); myPromises .then((arrayOfValues) => { console.log(arrayOfValues); }) .catch((rejectionReason) => { console.log(rejectionReason); });
2.ES8語法出了新的辦法來寫非同步操作,讓程式碼看起來像是同步的!
對比Promise寫的程式碼和async await寫出來的程式碼:
function nativePromiseVersion() { returnsFirstPromise() .then((firstValue) => { console.log(firstValue); return returnsSecondPromise(firstValue); }) .then((secondValue) => { console.log(secondValue); }); }
async function asyncAwaitVersion() { let firstValue = await returnsFirstPromise(); console.log(firstValue); let secondValue = await returnsSecondPromise(firstValue); console.log(secondValue); }
當你使用.catch()時,你不知道Promise呼叫鏈哪裡出錯了。而在新的ES8語法中,debugging更加容易準確:
async function usingTryCatch() { try { let resolveValue = await asyncFunction('thing that will fail'); let secondValue = await secondAsyncFunction(resolveValue); } catch (err) { // Catches any errors in the try block console.log(err); } } usingTryCatch();