Promise 與 Opendata

Opendata 是個很好用的練習資料,之前都是透過 jQuery 內建的 getJSON 或 AJAX 來完成資料串接取得,這篇將會透過XMLHttpRequest()來實作,並且搭配 Promise 的用法,載入一組資料之後再載另外一組資料,避免同時載入的情況發生。

Opendata 哪裡找

基本上我們的縣市政府網站,都有提供不少 Opendata 的資訊讓開發者使用,我自己很喜歡到「政府資料開放平臺」上面去挖寶,或是「台北市政府資料開放平臺」,這兩個平台的開放資料都是相當完整且容易介接。

在這邊列出一些我覺得還滿實用,至少都是每小時更新的 Opendata:

讀取 Opendata

原本要透過XMLHttpRequest()來讀取 Opendata,因為 jQuery 的 Ajax 即運用非標準的 XMLHttpRequest 物件,並配合伺服器端的 Script 進行通訊,詳細介紹可以參考下面這些文章。

延伸閱讀:你真的會使用 XMLHttpRequest 嗎?AJAX 上手篇XMLHttpRequest2 新技巧

但是在實作的過程中,遇到跨域的問題無法解決 ( 殘念 ),只好再回歸 jQuery 的.getJSON,畢竟支援 JSONP 還是比較方便,透過下面這段程式碼,可以載入空氣質的數據,並在載入完成後透過 console 顯示。

範例展示:demo-01.html

var url = "http://opendata2.epa.gov.tw/AQX.json";
var myArr;
$.getJSON(url,function(e){
  console.log(e);
});

同步處理 Opendata

因為載入 Opendata 需要時間 ( 看檔案大小與網路速度 ),加上 XMLHttpRequest 非同步的特性,如果你在程式碼最下面放個console(123);,就會看到 123 先顯示,然後才出現 Opendata 的資料 ( 如果你以為「放在最下面就會最後才出現」就錯了 )。

這時候最簡單的做法就是將 console 放到 getJSON 程式內,就可以看到 Opendata 先出現,接著才出現 123。

範例展示:demo-02.html

var url = "http://opendata2.epa.gov.tw/AQX.json";
var myArr;
$.getJSON(url,function(e){
  console.log(e);
  console.log(123); // 把 123 放在這邊
});

如果在只有一組 Opendata 的時候是很方便的,但誠如之前說過的,若是今天需要呼叫很多個檔案,相對來說得要使用一堆的 callback 來解決,這時候就可以把 Promise 派上用場,我們將$.getJSON變成一個 Promise 物件,這樣就可以透過.then不斷連結下去,也就可以在程式碼很乾淨的情況下,做到先載入完成一組 Opendata,再載入另外一組的流程。( 範例把兩個網址載入先後順序互換,就更能清楚看出來哪個先載入 )

範例展示:demo-03.html

var data1 = "http://opendata2.epa.gov.tw/AQX.json";
var data2 = "http://opendata.epa.gov.tw/ws/Data/RainTenMin/?format=json&callback=?"; // 加上 &callback=? 是 JSONP 格式

var myArr;
var p = function(url) {
  return new Promise(function(resolve, reject) {
    $.getJSON(url, function(e) {
      resolve([e, url]);  // 把多個值用成一個陣列傳遞下去 ( 因為 resolve 只有一個回傳值 )
    });
  });
}

p(data2).then(function(v) {
  console.log(v[1]);  // 顯示 opendata 網址
  console.log(v[0]);  // 顯示資料內容
  return p(data1);
}).then(function(v) {
  console.log(v[1]);  // 顯示 opendata 網址
  console.log(v[0]);  // 顯示資料內容
});

小結

Opendata 其實有很多好玩的資料等著我們去應用,學會 Promise 的用法之後更是如虎添翼,當然純前端串接 Opendata 一定會遇到一些安全性或是瀏覽器先天的問題,但相信透過現成技術的輔助和陸續支援,應該會有越來越多的發揮與想像空間。

有興趣瞧瞧其他新文章嗎?