JavaScript備忘録記事。
今年に入ってからNode.js + MongoDB(with mongoose)という組み合わせで仕事をしている。
ただ、プロジェクトの諸事情により、最近までNode.jsはPromiseが使えない古いバージョンを使わざる負えない状況だった。
具体的には0.10系。
そうなると困るのが同期的な処理をしたい時。
例えば"mongoose"を使って、指定した値を取得し処理をしたい時などに困るシーンが出てくる。
具体的には下記のような泥臭い処理を実装して凌いでいた。
var userModel = dataModel.getUserModel(); // "user"コレクションのMpdel取処理とする // userコレクションから"country"が"us"のデータを取得する userModel.find({"country" : "us"}, function(err, users) { // エラー処理 if(err) { errorHandling(); } // 取得件数が0件の場合の処理 if(users.length === 0) { notGetProcessing(); } // global変数として持たせることで共通的なカウンターとして使用 counter = users.length; console.log("find user count : ", counter; users.forEach(function(user) { // 取得したデータに対する処理。この場合、"Processing"に処理を移し、 // そちらでの処理が完了した後にGlobal変数である"counter"を-1していく setTimeout(function(a) { processing(a); },1000, user); }); // Global変数である"counter"が"0"になった時点で、 // 取得データに対する処理が全て完了したものとし、終了関数に処理を渡す setInterval(function() { if(counter === 0) { // End processing endProcess(); } }, 100); });
相当なスパゲティコードである。茹ですぎて完全に伸びている状態といったところか。
このように泥臭い処理をいたるところでしていたので、
相当コードがスパゲティになっていて、保守コストも高く付きそうになってしまっていた。
が、ある時点でNodeのバージョンが上がることになり、今ではバージョン6系で書いている。
Promiseも使えるようになったので、おかげで下記のように処理を変更できる。
(青臭いコードかもしれない。もし、もっとこうした方がスマートに出来るなどありましたら、コメントいただけると幸いです。。。)
// "country"が"us"のuserデータをPromiseで取得 function getUsUser() { let userModel = dataModel.getUserModel(); return userModel.find({"country" : "us"}).exec(); } // メイン処理 function main() { let promise = getUsUser(); promise.then(function(users) { // 取得件数が0件の場合の処理 if(users.length === 0) { notGetProcessing(); } console.log("find user count: ", users.length); // 取得した全データに対して処理を行う users.forEach(function(user) { processing(user); }); return users.length; }) .then(function(userCount) { console.log("Successful user count : ", userCount); // 終了処理 endProcess(); }) .catch(function(err) { conosole.log(err); // 終了処理 endProcess(); }); } // 実行関数 main();
毎日泥臭いコードを書いていたのは大変だったが、
いかにして無理やり同期的に処理させるか?と考えてコードをガリガリ書いていたのは、
それはそれでとても勉強になったと感じている。