Promise封裝非同步操作

2020-10-22 11:01:08

Promise是什麼:

Promise是非同步程式設計的一種解決方案。
JavaScript是單執行緒機制,所謂單執行緒就是按次序執行,執行完一個任務再執行下一個任務,同步就是一個單執行緒操作,同步程式設計會帶來一個嚴重的問題------阻塞,即:假如使用者在做某一個操作的時候,突然間進行一個非同步操作(網路請求、計時器),而非同步操作一般情況下是比較耗時的,此時程式碼執行到這個地方會出現阻塞,影響後續程式碼的執行,為了解決這個問題,我們一般在此時進行非同步操作,即在傳送網路請求的同時,繼續執行後續程式碼,然後網路請求結束後,通過回撥函數返回其結果。

同步操作遇到的問題:

以網路請求為例:第一次網路請求的結果中包含第二次網路請求的URL,第二次網路請求的結果中包含第三次網路請求的URL,第三次網路請求的結果中又包含第四次網路請求的URL…,此時就陷入了回撥地獄,為了避免回撥地獄的出現,使用Promise封裝非同步操作(此處也就是網路請求)。

Promise的三種所處的狀態:

在Promise封裝非同步操作之後會有三種狀態,pending:等待狀態,比如正在進行網路請求,或者定時器沒有到時間;fulfill:滿足狀態,當我們回撥了resolve()函數時,就處於該狀態,並且回撥then();reject:拒絕狀態,當我們主動回撥了reject時,就會處於該狀態,並且會回撥catch()方法

Promise的使用:

使用關鍵字new建立Promise範例物件,該Promise需要傳入兩個引數resolve 和 reject;resolve 和 reject本身又是兩個函數。

new Promise((resolve, reject) => {
    // 網路請求
    setTimeout(() => {
      // 此處為了模仿網路請求成功與失敗,將下方的resolve()註釋:代表模仿的網路請求失敗,執行catch(),若將reject()註釋掉,代表網路請求成功,執行then()
      resolve("請求到了資料");
      // Promise不希望我們在此處處理網路請求的結果,希望在then()方法中處理
      // reject("資料請求失敗");
    }, 1000)
  }).then(res => {
    // 此處的引數res代表成功請求到的資料
    console.log(res);
  }).catch(data => {
    // 此處的data代表網路請求失敗後的錯誤資訊
    console.log(data);
  });

  // 使用Promise封裝真正的網路請求
  let ajaxRequest = new Promise((resolve, reject) => {
    $.ajax({
      type: "get",
      url: "url地址",
      dataType: "json",
      success: res => {
        resolve(res);
      },
      error: res => {
        reject(res);
      }
    });
  });
  // 網路請求成功的處理
  ajaxRequest.then(res => {
    listArr = res.data.banner.list;
    console.log(listArr);
  });
  
  // 網路請求失敗的處理
  ajaxRequest.catch(res => {
    console.log(res.returnCode);
  });