Edited at

JavaScript の Promise で Movable Type の Data API から取得した非同期通信データを処理する

More than 1 year has passed since last update.

※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