結論
まぁ、結論から言うとそらしょうがないけどなんだかなって感じです。 grunt-typescript 作ってるときは意識してなかったから多分ミラクルが起こってたのかと思われます。
で、Grunt のタスクで非同期タスク作ろうとしてあれっ?てなったから調べたって話です。
とりあえず、公式ドキュメントどおりにやってみる
上を読むとどうやら、this.async
使えって書いてある。なので、下のように書いてみる。
module.exports = function(grunt){
grunt.registerTask("default", "非同期の確認", function(){
var done = this.async();
});
};
で、動かすとすぐ終わる。以下がコンソールの写し。予想では done
呼んでないからずーっと待機されると想像してました。想定外の結果。
user@machine /d/Work/TempSrc/gruntAsyncTest
$ grunt
Running "default" task
user@machine /d/Work/TempSrc/gruntAsyncTest
setTimeoutを仕掛けてみる
ドキュメントでは大抵 setTimeout
を仕掛けてるので同じように仕掛けてみる。
module.exports = function(grunt){
grunt.registerTask("default", "非同期の確認", function(){
var done = this.async();
setTimeout(function(){
console.log("終わるよ!");
}, 1000);
console.log("仕掛けたよ!");
});
};
動かしてみる。
user@machine /d/Work/TempSrc/gruntAsyncTest
$ grunt
Running "default" task
仕掛けたよ!
終わるよ!
user@machine /d/Work/TempSrc/gruntAsyncTest
おっ、setTimeout
の完了を待った模様。予想では、待たずにそのまま最初と同じように終わると思ってた。ちなみに、this.async
しないで、単純に流すと以下のようになる。
user@machine /d/Work/TempSrc/gruntAsyncTest
$ grunt
Running "default" task
仕掛けたよ!
Done, without errors.
user@machine /d/Work/TempSrc/gruntAsyncTest
"終わるよ!"ってメッセージが出て無い。で、よく見ると "Done, without errors." ってメッセージが出てる。今までは全く出て無かった。this.async()
を戻して、 setTimeout
の中で done
呼んでやると、ちゃんと "Done, without errors." ってメッセージが出るらしい。
Grunt 自体終わってる気がする
this.async
して done
せずに終わるとメッセージが出ないってことは Grunt は終わったと思ってない。と、思われる。でも、コンソール自体は終わる。ってことは、つまるところ node 側が処理が全部なくなったから終わりだね。って終わらしてるような気がする。ってことは Grunt は this.async
呼ばれても done
を渡すだけで、待機とかはなにもしてないのでは。と思われる。
ってことで、中を見てみた。
https://github.com/gruntjs/grunt/blob/master/lib/util/task.js#L236
async
が呼ばれたらフラグ立てて、complete
を実行する関数を返してる。
https://github.com/gruntjs/grunt/blob/master/lib/util/task.js#L253
で、処理実行して終わった後に、フラグ確認して、フラグ立ってなかったら complete
実行するけど、フラグ立ってなかったら何もしない。
ってことで、やっぱりそのまま流れていって、 node 的には処理が全部なくなったから終わらせてる感じ。
んー、 grunt が内部的に setTimeout
かなんかでくるくる回してフラグ確認してくれると使う側からはもっとわかりやすいんやけど、まぁ、パフォーマンスとかいろいろ考えると、何とも言えんとこやけど微妙な気がしないでもない。
クルクル回すとやっぱり終わらない
ってことで、書いてみた。やっぱり終わらないっす。
module.exports = function(grunt){
grunt.registerTask("default", "非同期の確認", function(){
var done = this.async(),
//クルクル回す処理
wait = function(){
setTimeout(function(){
console.log("待ってます。");
wait();
}, 1000);
};
//クルクル開始
wait();
console.log("仕掛けたよ!");
});
};
これコールスタック溜まりそう・・・。いや、 setTimeout
の時点でいったん消えそうやから大丈夫か?