2 - 非同步之Promise串 API


Posted by backas36 on 2021-07-21

這是 Fetch, Promise, Async & Await 的 第二篇,有興趣的朋友可以先看 非同步之認識Promise。

上一篇有簡單介紹 Promise 之後,我們可以使用 Promise 來串 API 試試看,API URL 一樣是使用上一篇的網址,如果有過期問題記得提醒我,謝謝!

Promise 串 API

先來長長的範例如下:

const api200 = 'https://run.mocky.io/v3/98c6ea3a-2359-429d-8be1-98396934af0f'
// 完全正常運作的 server

const api500 = 'https://run.mocky.io/v3/bf2b926c-0db4-4f98-b09a-1211d4da6038'
// 假裝 server error 回傳 500 的 api

const apiJsonError = 'https://run.mocky.io/v3/3bf6bbd8-6b7c-47f7-8b92-9efb2a0a8dfc'
// 回傳 200 但是 json 格式錯誤的 api

const apiWrongUrl = 'https://srun.mocky.io/v3/98c6ea3a-2359-429d-8be1-98396934af0f'




// 新建 promise
const requestPromise = new Promise((resolve, reject) => {
  var request = new XMLHttpRequest();
  request.open('GET', api200, true);

  request.onload = function () {
    if (this.status >= 200 && this.status < 400) {
      let data
      try {
        data = JSON.parse(this.response)
      } catch (error) {
        reject(error) // apiJsonError 的結果
        return
      }
      resolve(data) // api200的結果

    } else {
      reject(request.statusText)
      // api500 的結果 : Internal Server Error
      return
    }
  };

  request.onerror = function () {
    reject('request 有錯囉')
    //apiWrongUrl的結果
    return
  }

  request.send();
})
  .then(data => {
    console.log(data)
  })
  .catch(error => {
    console.log(error)
  })

此範例變數使用 api200 ,所以會成功執行 resolve(data),我們可以直接在後面接上 then 來接收 API 回傳的 data,也可以不用再後面直接加上去另外拆開寫成這樣也是可以

requestPromise.then(data => {
  console.log(data)
})
  .catch(error => {
    console.log(error)
  })

如果帶入其他三個錯誤的 API 變數的話,都會 reject,我們 then 的後面加上 catch,就可以接收 reject 傳過來的錯誤訊息。

你可能會想,那這樣有什麼好處呢? 有,我們可以利用 Promise 的語法來一直串 API,我們改寫一下 requestPromise 是可以接收參數,接著我們就可以利用這個參數,來串很多次的 API。

新增到範例用的API網站

先新增一個變數來放 API URL,並且改寫一下 requestPromise

 const api200 = 'https://run.mocky.io/v3/98c6ea3a-2359-429d-8be1-98396934af0f'
// 完全正常運作的 server

const api500 = 'https://run.mocky.io/v3/bf2b926c-0db4-4f98-b09a-1211d4da6038'
// 假裝 server error 回傳 500 的 api

const apiJsonError = 'https://run.mocky.io/v3/3bf6bbd8-6b7c-47f7-8b92-9efb2a0a8dfc'
// 回傳 200 但是 json 格式錯誤的 api

const apiWrongUrl = 'https://srun.mocky.io/v3/98c6ea3a-2359-429d-8be1-98396934af0f'

const apiUser = 'https://reqres.in/api/users'


// 新建 promise
const requestPromise = (apiURL) => {
  return new Promise((resolve, reject) => {
    var request = new XMLHttpRequest();
    request.open('GET', apiURL, true);

    // ... 以下與上個範例一樣
}

requestPromise(api200).then(data => {
  console.log(data)
  return requestPromise(apiUser)
}).then(userData => {
  console.log(userData)
})
  .catch(error => {
    console.log(error)
  })

可以看到我們可以利用 return 回傳一個 Promise ,接著就可以繼續 then 來串 API 剛剛加入的 API,非同步測試的 console.log ,就不示範了,可以自己 console 試試看。

以上介紹完簡單的 Promise 以及利用 Promise 來串 API 後,我們可以知道 Promise 可以讓我們做到非同步來執行程式,但其實我們還有更方便的 fetch 可以用。

來,再一篇。
1 - 非同步之認識Promise
2 - 非同步之Promise串 API
3 - 非同步之認識 fetch
4 - 非同步之認識 async/await


#非同步 #javascript #Promise







Related Posts

[9] 檔案讀寫 + 例外處理

[9] 檔案讀寫 + 例外處理

React(19) - ErrorBoundary

React(19) - ErrorBoundary

[Note] Node.js + express: Server & Routing

[Note] Node.js + express: Server & Routing


Comments