非同期実行時の変数共有(C〓とjavascript)
2168 ワード
C(※)で作成された委託例では、方法における局所変数を使用して、この変数のライフサイクルを長くすることがあります.この点はjavascriptと同じですが、この局部変数が変化中(例えばサイクル中)であると、微妙に違ってきます.
C〓〓の例:
javascriptを見て、setTimeoutを使って非同期を作る場合:
以下でこの問題を解決します.もし共有変数が私達の期待したものではないなら、C((abs)に臨時変数を入れて、taskの参照を臨時変数tに賦課します.tのライフサイクルは各自の委託例に従って、共有変数taskの問題を解決しました.
根本的な理由は、javascriptの変数はブロックレベルの作用領域がないため、たとえ宣言された変数jがforループ内にあるとしても、その作用領域は依然としてprocess関数の局所的な作用領域であるため、jの参照はサイクルとともに変化している.原因がわかれば簡単です.
スコープチェーンには異なる呼び出しオブジェクトが含まれています.
変数の1つの参照を共有していますが、変数の指向性の変化は、実際の参照を引き起こすことはありません.
スコープ、基本は簡単ではない.
C〓〓の例:
void Process()
{
foreach (ITask task in GetTasks())
{
ThreadPool.QueueUserWorkItem(new WaitCallback(
delegate{
task.DoWork();
})
);
}
}
非同期的にタスクのセットを実行する必要がありますが、最後にはその一部だけが実行される可能性があります.その理由は、匿名の方法による変数共有であり、趙さんの文章を参照することができます.javascriptを見て、setTimeoutを使って非同期を作る場合:
function process(){
for(var i=0;i<5;i++){
setTimeout(function(){
alert(i);
},0);
}
}
C(※)と同様に変数共有の問題もありますが、alertが出てくるのは全部5です.以下でこの問題を解決します.もし共有変数が私達の期待したものではないなら、C((abs)に臨時変数を入れて、taskの参照を臨時変数tに賦課します.tのライフサイクルは各自の委託例に従って、共有変数taskの問題を解決しました.
void Process()
{
foreach (ITask task in GetTasks())
{
ITask t=task;
ThreadPool.QueueUserWorkItem(new WaitCallback(
delegate{
t.DoWork();
})
);
}
}
私たちが期待している効果を達成することができます.この方法でjavascriptのコードを改造します.function process(){
for(var i=0;i<5;i++){
var j=i;
setTimeout(function(){
alert(j);
},0);
}
}
しかし、私たちが期待していた効果はまだ達成されていません.根本的な理由は、javascriptの変数はブロックレベルの作用領域がないため、たとえ宣言された変数jがforループ内にあるとしても、その作用領域は依然としてprocess関数の局所的な作用領域であるため、jの参照はサイクルとともに変化している.原因がわかれば簡単です.
function wrap(fn,data){
setTimeout(function(){
fn(data);
},0);
}
function process(){
for(var i=0;i<5;i++){
wrap(alert,i);
}
}
もう一つのやり方は:function process(){
for(var i=0;i<5;i++){
(function(j){
setTimeout(function(){
alert(j);
},0);
})(i);
}
}
実は、両方はもう一つの関数を包装しています.(後の方は匿名です.)そのたびに実行します.スコープチェーンには異なる呼び出しオブジェクトが含まれています.
変数の1つの参照を共有していますが、変数の指向性の変化は、実際の参照を引き起こすことはありません.
スコープ、基本は簡単ではない.