1. 程式人生 > 實用技巧 >深入淺出JS中的非同步程式設計(ES6 VS ES8)

深入淺出JS中的非同步程式設計(ES6 VS ES8)

介紹下為什麼有非同步程式設計以及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();