Promiseの事始め

最近、Node上でのPromiseの勉強を全く0からしてちょっとだけ解ってきたので、自作のcodeをチラシの裏がてらひたすら貼り付けます。ここでは、Node.js上でbluebirdを使っています。一つでも参考になる物があれば幸いです。

なお、coffee script版を知りたい人は、一旦xxx.jsとして保存して、js2coffee xxx.jsを実行！

#coffee script化した時にハマッた箇所
### ".catch" がjs2coffeeでエラーを吐く
* 原因の詳細は[こちらを参照](https://github.com/js2coffee/js2coffee/issues/157)
* js→coffee変換は別の[このTool使う事で回避できました](http://js2coffee.github.io/js2coffee-redux/#try:var%20memcached%3Drequire%28%27memcache%27%29%3B%0Amemcached.delete%28foobar%29%3B)

### 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');
    });

});
```