※JavaScript のPromise について、勉強がてら記述しました。誤記などありましたらご指摘ください。
Movable Type の Data API からJSONを取得。
取得した データを、JavaScriptで加工して、表示したい。利用したい。
そんなシチュエーションがあると思います。
例として、API経由で取得したデータを、別関数に引き渡すというシチュエーションで考えてみます。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
// Movable Type のData APIから、記事データを取得して、変数listに格納
const list = $.ajax('http://your-mt/mt-data-api.cgi/v3/sites/site_id/entries');
// 変数listを表示
console.log(list);
</script>
このコードでは、Data API 経由で取得した記事データを、console.logで表示しようとしています。しかし、上記の実行結果は以下のようになり、期待通りに記事のデータを表示できません。
これは
- JavaScript で Data APIを利用するときは、非同期通信で処理を行っている
- JavaScript は、非同期通信のレスポンスを待たずに処理を実行する
- 結果として、Data API から取得したデータを受け取る前に、console.logが実行済になってしまう
ことから起こる現象となります。
非同期通信を行っている最中(readyState が 1 の状態) 、つまり通信中の状態で、データを完全に取得する前に console.logを実行してしまい、記事データが期待通りに表示されない状態となります。
JavaScriptでは、非同期通信で取得したデータを処理するために Promise という概念があります。Promise を利用すると、Data API で取得したデータを上手く処理することができます。
Promiseのメリット
Promiseは、ECMAScript2015 から標準仕様として採用されています。
Promise を使うと、JavaScript の非同期通信の結果を待って、次の処理にデータを引き渡すことができます。
Promise については、以下のドキュメントが非常に詳しいため、こちらをご参照ください。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise
http://azu.github.io/promises-book/
※Promise は各種ブラウザで利用できますが、IEではサポートされていません。
Promise を使って、Data APIから取得したデータをうまく処理する
実際にPromise を使って、Movable Type の Data API からデータを取得し、別の関数に渡して表示してみます。
sample-1 JavaScript SDK を使った場合
以下は、Movable Type の Data API 用 JavaScript SDKを使い、console.logにデータを渡して表示する例です。JavaScript SDK のラッパー関数[getEntries]を定義して、Promise のオブジェクトを生成します。Data API との通信が終わったら、次の関数であるconsole.logに値を渡して、表示します。
<script src="http://your-mt/mt-static/data-api/v3/js/mt-data-api.js"></script>
<script>
const api = new MT.DataAPI({
baseUrl: "http://your-mt/mt-data-api.cgi",
clientId: "your-client-id"
});
// MTのブログIDを変数 siteId に格納
const siteId = IDの数字;
function getEntries() {
return new Promise((resolve, reject) => {
api.listEntries(siteId, function(response) {
resolve(response);
});
});
}
getEntries().then(function(response) {
console.log(response);
});
</script>
上記のコードの実行すると、以下のように、JavaScript のオブジェクトデータが表示されます。非同期通信の処理を待って、取得したデータを次の関数に引き渡しできていることがわかります。
sample-2 jQueryを使った場合
jQueryを使った場合は、以下のようなコードになります。
実行結果は、sample-1と同じです。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
function getEntries() {
return new Promise((resolve, reject) => {
const response = $.ajax('http://your-mt/mt-data-api.cgi/v3/sites/site_id/entries')
resolve(response);
});
}
getEntries().then(function(response) {
console.log(response);
});
</script>
sample-3 Promise.resolve を使う
jQueryのajax関数は、Thenable なオブジェクトを返します。このため、Promise のショートカットである Promise.resolve を使った書き方ができます。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
const list = $.ajax('http://your-mt/mt-data-api.cgi/v3/sites/site_id/entries');
Promise.resolve(list).then(function(response) {
console.log(response);
});
</script>
sample-2 よりも、少しスッキリした書き方ができることがわかります。この実行結果は、sample-1,
sample-2 と同じとなります。
今回使った、Movable Type Data API のエンドポイントについては、以下をご参照ください。
https://www.movabletype.jp/developers/data-api/
https://www.movabletype.jp/developers/data-api/v3-reference.html#entries
https://github.com/movabletype/mt-data-api-sdk-js/wiki/DataAPI-SDK-japanese-MT.DataAPI