1. 程式人生 > >前端複習--javascript 任務佇列 與 setTimeout()的深入學習

前端複習--javascript 任務佇列 與 setTimeout()的深入學習

首先參考了《高程》的P203和P609:

javascript是單執行緒的,所以在一定時間內只能執行一段程式碼。為了控制程式碼的執行順序,JavaScript有一個任務佇列。任務會按照他們被加入佇列的順序執行。

而  SetTimeOut(任務,多久之後將此任務加入任務佇列);

下面有幾個例子,可以充分說明上面的觀點。

例子一:(來自阿里的筆試題)

單選題:

對於下列程式執行結果,符合預期的是

function f1() {

    console.time('time span');

}
function f2() {

    console.timeEnd('time span');

}

setTimeout
(f1, 100); setTimeout(f2, 200); function waitForMs(n) { var now = Date.now(); while (Date.now() - now < n) {} } waitForMs(500);
  • A、time apan:700.077ms
  • B、time apan:0.066ms
  • C、time apan:500.077ms
  • D、time apan:100.077ms
答案是B。

程式碼執行到setTimeout(f1,100),告訴js:  100ms後將f1加入任務佇列;

程式碼執行到setTimeout(f2,200),告訴js:  200ms後將f2加入任務佇列;

程式碼執行到waitForMs(500)時,js開始數數,數到100時,f1加入任務佇列

                                                                               數到200時,f2加入任務佇列

此時任務佇列裡,waitForMs(500)後面就是排著f1 , f2;

f1啟動計時器,f2關閉計時器,兩者的執行都很快,事件間隔不到1ms;

例子2:來自stack overflow 操作任務佇列

console.clear();
console.log("a");
setTimeout(function(){console.log("b");},1000);
console.log("c");
setTimeout(function(){console.log("d");},0);

A request comes in, and JS engine starts executing the code above step by step. 

The first two calls are sync(同步) calls. 

But when it comes to setTimeout method, it becomes an async execution. But JS immediately returns from it and continue executing, which is called Non-Blocking or Async. And it continues working on other etc.

The results of this execution is the following:

a c d b


我們說過,我們要操作任務佇列,動一點小手腳:

console.clear();
console.log("a");
setTimeout(function(){console.log("b");},100);
console.log("c");
function waitForMs(n) {    
	var now = Date.now();    
	while (Date.now() - now < n) {}
}     
waitForMs(500);
setTimeout(function(){console.log("d");} ,0);

a c b d

自己想想為什麼把。

wait!  看看下面的程式碼是怎麼輸出的:

for(var i=1;i<=3;i++){ setTimeout(function(){ console.log(i);    },0);  };

for(var i=1;i<=3;i++){
  (function(i){
    setTimeout(function(){
      console.log(i);   
  },0);
  })(i);
   
};