最近、Node上でのPromiseの勉強を全く0からしてちょっとだけ解ってきたので、自作のcodeをチラシの裏がてらひたすら貼り付けます。ここでは、Node.js上でbluebirdを使っています。一つでも参考になる物があれば幸いです。
なお、coffee script版を知りたい人は、一旦xxx.jsとして保存して、js2coffee xxx.jsを実行!
coffee script化した時にハマッた箇所
".catch" がjs2coffeeでエラーを吐く
- 原因の詳細はこちらを参照
- js→coffee変換は別のこのTool使う事で回避できました
Webstormが".then", ".catch" を正しくindent処理してくれない
- 私はjavascriptのIDEにwebstorm (v8.0)を使っていますが、promiseの.then, .catchを正しくcoffee scriptのindent処理をしてくれませんでした (手動でindentを修正すれば勿論動くようになります)
HTTP Getでの事例
単純なHTTP GetのAsync
reject側の処理が見たければ、http://www.google.co.jp/ → http://www.google.co.jp/hoge など存在しないURLにしてみて実行!
var promise = require('bluebird');
var request = require('request');
router.get('/', function (req, res) {
var get_http1 = new promise(function (resolve, reject) {
console.log('start http get to google...');
request('http://google.co.jp/', function (error, response) {
if (!error && response.statusCode == 200) {
resolve(response);
} else {
reject(response);
}
});
});
get_http1.then(function (response) {
console.log('http get to google done! ');
console.log(response.statusCode);
}).catch(function(error) {
console.log('http get failed...');
console.log(error.statusCode);
});
});
Promiseを複数繋げてみる(Chain)
return で次に呼びたいpromiseのobjectを返してあげると、連続して呼べます。
あと、最後にconsole.log('hogege'); とありますが、これは(当たり前ですが) get_http1.then ...から続く非同期処理を待たずに処理されます。
router.get('/', function (req, res) {
var get_http1 = new promise(function (resolve, reject) {
request('http://google.co.jp', function (error, response, body) {
if (!error && response.statusCode == 200) {
resolve(response);
} else {
reject(response);
}
});
});
var get_http2 = new promise(function (resolve, reject) {
request('http://yahoo.co.jp', function (error, response, body) {
if (!error && response.statusCode == 200) {
resolve(response);
} else {
reject(response);
}
});
});
var just_wait = new promise(function (resolve, reject) {
setTimeout(resolve, 5000);
});
get_http1.then(function (response) {
console.log('http get to google done! ');
console.log(response.statusCode);
return just_wait;
}).then (function () {
console.log('wait 5000msec done! ');
return get_http2;
}).then (function (response) {
console.log('http get to yahoo done!');
console.log(response.statusCode);
}).then(function(){
res.end('Async function done');
});
console.log('hogege');
});
mongodbでの事例
Mongodbを使って、DB openしてRecordを1件 dump
mongooseじゃなくってゴメンナサイ。
var mongodb = require('mongodb');
var promise = require('bluebird');
router.get('/', function (req, res) {
var DB_name = 'test_db';
var Coll_name = 'test_collection';
function open_db (database_name){
return new promise(function (resolve, reject) {
mongodb.MongoClient.connect('mongodb://localhost:27017/' + database_name, function (error, database) {
if (error) {
reject(error);
} else {
resolve(database);
}
});
});
}
function dump_one_record (database, collection_name){
return new promise(function (resolve, reject) {
var collection = database.collection(collection_name);
collection.find().limit(1).toArray(function (error, item) {
if (!error){
resolve(item);
}else{
reject(error);
}
});
});
}
open_db(DB_name).then(function (database) {
return dump_one_record(database, Coll_name);
}).then (function (item) {
console.log(JSON.stringify(item));
res.end('Mongo open success');
}).catch(function (error) {
console.log(error);
res.end('Mongo open failed');
});
});