Q での非同期処理の分散数を qlimit で限定する

## package.json

```json
{
  "name": "qlimit-sample",
  "version": "1.0.0",
  "description": "",
  "scripts": {},
  "author": "",
  "license": "MIT",
  "devDependencies": {
  },
  "dependencies": {
    "command-line-args": "^3.0.0",
    "moment": "^2.13.0",
    "q": "^1.4.1",
    "qlimit": "^0.1.1",
    "sleep-async": "^1.0.1"
  }
}
```

## run.js

```js
var exec = require('child_process').exec;
var moment = require('moment');
var Q = require('q');
var qlimit = require('qlimit');
var asleep = require('sleep-async')();
var limit = qlimit(3);

var tasks  = [];
for(var i = 0; i < 10; i++){
    tasks.push("task_" + i);
}

function log(message){
    var dict = {};
    dict["time"] = moment().format();
    dict["message"] = message;
    console.log(JSON.stringify(dict));
}

Q.when(1).
then(function(){
    var d = Q.defer();
    log("init_1");
    asleep.sleep(3000, function(){
    	log("init_2");
        d.resolve();
    });
    return d.promise;
}).then(function(){
    var d = Q.defer();
    Q.all(tasks.map(limit(function(task) { 
        var _d = Q.defer();
        try{
            command = "sleep 2";
            exec(command, (error, stdout, stderr) => {
                log(task + "-1");
                asleep.sleep(2000, function(){
                    log(task + "-2");
                    _d.resolve();
                });
            });
        } catch( error ){
             log(error);
        }
        return _d.promise;
    })))
    .then(function(data){
        d.resolve();
    });
    return d.promise;
}).then(function(){
    var d = Q.defer();
    log("shutdown_1");
    asleep.sleep(3000, function(){
    	log("shutdown_2");
        d.resolve();
    });
    return d.promise;
}).catch(function(error){
    log(error);
}).done(function(){
    log("done");
});
```

で、

```zsh
nvm use v4.3.2
npm install
node run.js
```

などとすると、

```
{"time":"2016-08-28T03:52:18+09:00","message":"init_1"}
{"time":"2016-08-28T03:52:21+09:00","message":"init_2"}
{"time":"2016-08-28T03:52:23+09:00","message":"task_0-1"}
{"time":"2016-08-28T03:52:23+09:00","message":"task_1-1"}
{"time":"2016-08-28T03:52:23+09:00","message":"task_2-1"}
{"time":"2016-08-28T03:52:25+09:00","message":"task_0-2"}
{"time":"2016-08-28T03:52:25+09:00","message":"task_1-2"}
{"time":"2016-08-28T03:52:25+09:00","message":"task_2-2"}
{"time":"2016-08-28T03:52:28+09:00","message":"task_3-1"}
{"time":"2016-08-28T03:52:28+09:00","message":"task_4-1"}
{"time":"2016-08-28T03:52:28+09:00","message":"task_5-1"}
{"time":"2016-08-28T03:52:30+09:00","message":"task_5-2"}
{"time":"2016-08-28T03:52:30+09:00","message":"task_3-2"}
{"time":"2016-08-28T03:52:30+09:00","message":"task_4-2"}
{"time":"2016-08-28T03:52:32+09:00","message":"task_7-1"}
{"time":"2016-08-28T03:52:32+09:00","message":"task_6-1"}
{"time":"2016-08-28T03:52:32+09:00","message":"task_8-1"}
{"time":"2016-08-28T03:52:34+09:00","message":"task_7-2"}
{"time":"2016-08-28T03:52:34+09:00","message":"task_6-2"}
{"time":"2016-08-28T03:52:34+09:00","message":"task_8-2"}
{"time":"2016-08-28T03:52:36+09:00","message":"task_9-1"}
{"time":"2016-08-28T03:52:38+09:00","message":"task_9-2"}
{"time":"2016-08-28T03:52:38+09:00","message":"shutdown_1"}
{"time":"2016-08-28T03:52:41+09:00","message":"shutdown_2"}
{"time":"2016-08-28T03:52:41+09:00","message":"done"}
```

と 3 tasks ずつ非同期で実行してくれる。