LoginSignup
12
13

More than 5 years have passed since last update.

Promiseの事始め

Last updated at Posted at 2015-01-29

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

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

coffee script化した時にハマッた箇所

".catch" がjs2coffeeでエラーを吐く

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

});
12
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
13