nodejsは、コールバック関数を正しく使用します.

2912 ワード

nodejs非同期の作業メカニズムのため、コールバック関数がよく使われます.
しかし、初心者のnodejsも間違えやすいです.
最も一般的なのは、非同期のフィードバックがないことです.
function foo(data,callback){
    console.log(data);
    if(data=='data'){//      data   0
	console.log("do something");
	callback(0);
    }else{//         
        callback('    ');
    }
}
foo('data',function(err){
	console.log(err);
});
はこのようにして予想される効果を達成したが、その本質はまだ同期された方法である.
コールバックを使わないとコードが読みやすくなります.
function foo(data){
	console.log(data);
	if(data=='data'){//      data   0
		console.log("do something");
		return 0;
	}else{//         
		return '    ';
	}
}
var result=foo('data');
console.log(result);
do somethingが複雑な計算であれば、非同期処理が必要であれば、以下のように修正することができる.
function foo(data,callback){
	process.nextTick(function(){
		console.log(data);
		if(data=='data'){//      data   0
			console.log("do something");
			callback(0);
		}else{//         
			callback('    ');
		}
	});
	
}
foo('data',function(result){
	console.log(result);
});
console.log('after foo ');
で結果が見られます.after fooは一番前に印刷されます.
ドsomething非同期処理
もう一つの問題は、コールバック関数が外部変数にアクセスすることです.以下の例を見てください.
var http=require("http");
var redis=require("redis");
var client=redis.createClient();

var counter=0;
var server=http.createServer(function(req,res){
	counter++;
	console.log(" "+counter+"    start ");
	client.keys("*",function(err,reply){		
		console.log(" "+counter+"    end   ");
		res.end("data");
	});
			
}).listen(3000);
console.info("server startup at 3000");
server.on("error",function(err){
	console.err(err);
});
上のコードは主に、要求が入ったら、統計器counter+をあげて、redisを調べて、redisを調べてからブラウザに応答resを送ります.
この動作を調べるのに時間がかかるように、私はredisに10 wの記録を加えました.つまり10 wのkeyがあります.keys*命令を実行するには6、7秒ぐらいかかります.
ブラウザを開き、三つのページを開いて、アドレスバーに入力します.http://localhost:3000/?r=1231 (3つの改ページのrパラメータが違っています.要求を送信せずにブラウザがキャッシュを使用することを避けることができます.)
業務上、次のような結果が見られます.
server startup at 3000
 1    start 
 1    end   
 2    start 
 3    start 
 3    end   
 3    end   

二つ目の要求はstartだけendがないと見られますが、第二の要求は応答していません.ブラウザに戻ってみると、三つのページが正常です.
事実は2番目の要求応答で、counterはすでに3に修正されました.
このような需要はnodejsの中で比較的によくあります.
解決するのも簡単です.クローズドを使えばいいです.
var counter=0;
var server=http.createServer(function(req,res){
	counter++;
	console.log(" "+counter+"    start ");
	client.keys("*",function(){
		var c=counter;
		return function(err,reply){		
			console.log(" "+c+"    end   ");
			res.end("data");
		}
	}());
			
}).listen(3000);
要求が入ったばかりの時のカウンタをvar cに存在します.各応答には自分の対応するcがあります.間違いがありません.
server startup at 3000
 1    start 
 2    start 
 1    end   
 2    end   
 3    start 
 3    end