Edited at

Node.jsの人はちゃんとsleepしてください

More than 5 years have passed since last update.

Node.jsでがんばりすぎると別のプロセスに迷惑だから長いことかかる処理は sleep() みたいなのを挟みながらやりたいなー。

と思ってググった結果がこうですよ。

https://github.com/ErikDubbelboer/node-sleep

  binding = {

sleep: function(s) {
var e = new Date().getTime() + (s * 1000);

while (new Date().getTime() <= e) {
/* do nothing, but burn a lot of CPU while doing so */
/* jshint noempty: false */
}
},

だめですね。これCPU使いまくり。

まあ、CPUがいくら発熱してもいいよって思っても、制御が別のタスクに行かないのはアウトです。たとえばこれがサーバのリクエストハンドラに使われてたら、みんな一定秒数遅れてページ表示される、んじゃなくて、 サーバーが一定秒数止まる ことになる。つまり、そのリクエストに3人来たら、3人目は1人目の3倍待たないといけない。

もしコールバック連鎖を使ってるバックグラウンドスレッド(DBのバッチ更新トランザクションとか)があった場合は、sleep してメイン処理を待機させようとしたつもりが、肝心のバックグラウンド処理を止めてしまうことに。

CPUを使いすぎることはREADMEにちゃんと書いてあるんですが、マルチタスクが止まるって点には言及してない。


On windows the module will fall back to a while loop which will use 100% CPU!


まーね、これはネタリポジトリだろうしね...

https://www.npmjs.org/package/sleep


186 downloads in the last day

1001 downloads in the last week

4741 downloads in the last month


え、いいのかきみたち! コレジャナイってなるよ。

だいたい誰がこんな...

Nodeビギナーズブック » Node.jsチュートリアル » Node.js 教程 #ブロッキングとノンブロッキング

おまえかー!! まったくもー、「悪い例」ってちゃんと書いといてよ。

というわけで、綺麗なスリープはこう書くといいよというのを、async.js 使って説明します。

var async = require('async');

var repeating = 0;
async.forever(function(callback) {
async.series([
function(callback) {
console.log("どっこらせー");
setTimeout(callback, 1000);
},
function(callback) {
console.log("よっこいせー");
setTimeout(callback, 1000);
},
function(callback) {
if (++repeating < 5) {
callback();
} else {
console.log("おしまい");
}
}
], callback);
}, function(err) {
console.log(err);
});

setTimeout() のコールバックが async の次のステップに行くトリガーになるのがポイント。

ちなみにコールバック地獄版はこちら。

var repeating = 0;

(function() {
var redoFunc = arguments.callee;
console.log("どっこらせー");
setTimeout(function(){
console.log("よっこいせー");
setTimeout(function() {
if (++repeating >= 5) {
console.log('おしまい');
} else {
redoFunc();
}
}, 1000);
}, 1000);
})();

上級者はもっといい方法を知ってるのかなぁ。