jquery: bluebird を使って JSON.parse を非同期に

別名: してみたがあまりワタシのケースでは嬉しくもなかった話。

bluebirdjs。大抵この手の「お便利ライブラリ」には、何かほかの作業中にふと存在に気付く場合がほとんどで、「こんなもんが欲しい」として自力で探すことの方が少数派だったりする、ワタシの場合。なんかしらのデモのソースを読んだりすることが多いから。これも cytoscape.js の色んなデモであちこちで使われていたんで、いやでも目にしてたヤツ。

で、「何してくれるものかわからんが」状態でさえ「いつかは使いたいかな」と思っていたのは、「たぶん非同期処理をスマートに書けるヤツに違いない」と「コードの見かけ」だけで十分に察することが出来ていたから。事実そういうことらしい

そしてなんで今はじめて「Promise てみっか」と思ったかは、「JSON.parse が非同期でないから」という…、相反するニーズだったりすんのね(コールバックを受け付けるが目的とは違う)。つまり「JSON parse async」で google ちゃんしたらいつものごとく StackOverflow がヒットして。あぁ、だったらもう bluebird しちゃおっかなぁ、と思った、て話。

ドキュメントが「明快」とは思えなかったけれど、「推測」で書いた一発目ですぐに目的のものになった:

 1 $('#do-import').on("click", function(e) {
 2     var input = $('#import-data')[0];
 3     var file = input.files[0];  // input type="file" で受け取った json ファイル名
 4     var fr = new FileReader();  // 読み込み野郎マ○ガイバー
 5     // ...
 6     //
 7     function _update_with_imported(imported) {
 8         // 読み込んでパースした結果でごにょごにょするコードがここに..
 9     }
10     fr.onload = function () {
11         //var imported = JSON.parse(fr.result); // もともとこうだった
12         //_update_with_imported(imported); // もともとこうだった
13 
14         // Promise: required bluebird.
15         //   CDN: https://cdn.jsdelivr.net/bluebird/3.5.0/bluebird.min.js
16         //   HOME: http://bluebirdjs.com/docs/getting-started.html
17         console.log("end reading, and start parsing");
18         Promise.resolve(fr.result).then(JSON.parse).then(function(imported) {
19             console.log("end parsing");
20             _update_with_imported(imported);
21             });
22         console.log("promised.");
23     };
24     console.log("start reading");
25     fr.readAsText(file);
26 });

完全に期待通りの振る舞いをしてくれた。

ただし…。

「ワタシのケース」限定の話になりうる話だけれど、「なんで非同期でやりたいのか」なんてのは無論「処理時間がかかるから」であろう。長時間 parse から返ってこない間、プログレスバーでも弄んでおきたいわけである。けど…、「遅いのは _update_with_imported であって JSON.parse なんぞ一瞬」なのであった…。

ともあれ bluebirdjs、これは日常使いにしようっと。便利過ぎるわ。(今回のケースはちょっと普通の例ではなかったけど。)



Related Posts