forサイクルについてsetTimeoutを参照します.

2546 ワード

テーマ1:
var a=[1,2,3];
		var len=a.length;
		for(___){
			setTimeout{function(){
				console.log(__);
			},0}
		}
		
aを出力する全ての項目が要求されます.
このテーマはJavaScriptのシングルスレッドとset Timeoutの非同期特性を考察します.
【注】:JavaScriptエンジンは単一スレッドで実行されています.ブラウザの実行中は一つのスレッドだけがjsプログラムを実行しています.ブラウザのカーネルはマルチスレッドであり、彼らはカーネルコントロールの下で互いに協力して、同期を維持する.一つのブラウザは少なくとも三つの常駐スレッドを実現する.JavaScriptエンジンスレッド、GUIレンダリングスレッド、ブラウザイベントトリガスレッド.
  • JavaScriptエンジンはイベントドライバの単一スレッドに基づいて実行され、Jsエンジンは常にジョブキュー中のタスクの到来を待っています.そして処理します.ブラウザはいつでもjsスレッドだけがjsプログラムを実行しています.
  • GUIレンダリングスレッドは、ブラウザのインタフェースのレンダリングを担当しています.インターフェースが再描画される必要があるときや、ある操作によってフィードバックが生じると、GUIレンダリングスレッドとjsエンジンは相互に反発しています.Jsエンジンが実行されると、GUIスレッドは保留され、GUI更新はキューに保存されます.
  • イベントトリガスレッドは、イベントがトリガされると、処理対象のキューの最後にイベントを追加し、jsエンジンの処理を待つ.これらのイベントは、jsエンジンが現在コードブロックを実行しており、setTimeoutのようなブラウザカーネルからの他のスレッド、マウスクリック、ajax非同期要求などがありますが、jsのシングルスレッド関係のために、これらのイベントはすべてjsエンジン処理を待ち続けなければなりません.
  • は、スレッドに同期コードがないという前提で非同期コードを実行する.
  • --以上の情報はhttps://www.zhihu.com/people/fredshare.
    上のタイトルでsetTimeoutは非同期のコードです.setTimeoutで設定された待ち時間が0であってもすぐに実行されません.forサイクルコードは同期ですので、forサイクルが終わったらsetTimeoutを実行します.この場合、従来のforループを使用して、setTimeoutでa[i]を印刷するとundefinedが発生する場合があります.このとき、forループの外にローカル変数jを定義することができる.印刷時にa[j++]を印刷するとa配列のエルゴードが可能です.
    コードは以下の通りです
    var a=[1,2,3,4];
    			var i,len=a.length;
    			var j=0;
    			for(i = 0; i < len; i++) {
    				(function(i) {
    					setTimeout(function() {
    						console.log(a[j++]);
    					}, 0);
    				})(i)
    			}
     或者 
       
      
    for(i = 0; i < len; i++) {
    				(function(i) {
    					setTimeout(function() {
    						console.log(a[i]);
    					}, 0);
    				})(i)
    			}
    -----http://m.blog.csdn.net/article/details?id=51177648
    テーマ2:
    for(var i = 1; i <= 3; i++) {
                    setTimeout(function() {
                        console.log(i)
                    }, 0)
                }
                //4,4, 4
    
    上のコードブロックは3つの‘4’をプリントしますが、私達が予想していた結果は1、2、3をプリントします.
    なぜかというと、setTimeoutのiは対外層iの参照であるからである.setTimeoutのコードが解釈されると、実行時はiの参照だけが記録され、値ではない.setTimeoutがトリガされると、3つのsetTimeoutのiは同時に値をとり、それらはすべて外層の同じiを指すので、そのiの値は反復が完了すると4になるので、3回の‘4’を印刷した.
    私たちが予想した結果を得るために、私たちはi賦を局所的な変数にして、外層反復の影響を脱することができます.
    for (var i = 0; i <= 3; i++) {
      (function (idx) {
        setTimeout(function () {
          console.log(idx);
        }, 5);
      })(i);
    }
    または:
    var j=0; 
    for(i = 0; i <=3; i++) {
    			(function(i) {
    				setTimeout(function() {
    				console.log(a[j++]);
    				}, 0);
    			})(i)
    		}