iT邦幫忙

0

JS AJAX、同步非同步、Promise

甚麼是 AJAX

Asynchronous JavaScript and XML
可以使網頁與伺服器進行非同步更新,不需要重新載入網頁的技術。
較舊的PHP網站,可能有區域資料變動,就需要重新向伺服器請求,並在伺服器端重新渲染HTML,再由瀏覽器接收新的HTML造成頁面刷新,但是更改的區域又很小,造成不必要的資源浪費。
AJAX則資料皆在客戶端處理,不需要刷新頁面,即可更新DOM。

同步、非同步概念

  • JS 是一個非同步語言
    執行帶有 setTimeout / API Call 不會停下來等待完成後,才進行下一個,因此可能出現錯誤。
    Ex: 取得伺服器資料時太慢,後續程序得不到資料而報錯。

  • 同步: 看似所有動作同時進行,實則相反!!!
    一個動作執行完,才作下一個動作

  • 非同步: 可以同時進行多個任務
    不需要等待上一個動作完成,才作下一個動作

如何解決非同步帶來的問題

解法1 CallBack

CallBackHell:
如果太多需要順序性的程式,就會造成多層巢狀,而難以維護。

  let funcA = function (callback) {
    window.setTimeout(() => {
      console.log('function A')
      // 如果 callback 是個函式就呼叫它
      if (typeof callback === 'function') { callback() }
    }, 3000)
  }
  
  let funcB = function () {
    window.setTimeout(() => { console.log('function B') }, 1000)
  }

  // 模擬 funcA 資料回傳較慢,導致 funcB 會先執行
  funcA()
  funcB()
  // 為了確保 funcA 內容先作完,才作 funcB 內容
  funcA(funcB)

解法2 Promise

支援度差的瀏覽器可用 es6-promise polyfill

  • 要提供函式有promise功能,使函式return promise物件即可

  • 串接函式順序 使用 then,resolve才會繼續作下去

  • 若不管順序,只求全部完成使用 Promise.all()

Promise 物件有三種狀態

Promise 回傳結果只有 完成(resolve) 或 拒絕(reject)

  1. pending 初始狀態
  2. fulfilled 操作完成
  3. rejected 操作失敗
  // 宣告一個Promise
  const p1 = new Promise((resolve, reject) => {
    resolve('OK') 
    // reject(new Error('Error'))
  })

  // 提供 Function 有 promise功能
  function promiseFunc(url) {
    return new Promise((resolve, reject) => {
      resolve('OK')
      // reject(new Error('Error'))
    })
  }

  // 串接函式順序 使用 then
  funcA().then(funcB).then(funcC)

  // Promise.all()
    Promise.all([funcA(), funcB()])
      .then((result) => {
        console.log(result)
      }).catch((err) => { console.error(err) })

尚未有邦友留言

立即登入留言