關於setTimeout的面試題


  於地鐵上看了一篇帖子,關於setTimeout的面試題,覺得見得多,記錄,以學習之。

  我們都知道,這樣的一個例子:

for ( var i = 0;i<5; i++) {
    console.log(i);

結果不用說,直接輸出為0,1,2,3,4;

for( var i = 0;i<5;i++) {
    setTimeout(function() {
        console.log(i);
    },1000)
}//5,5,5,5,5

這個可能不熟悉的人不怎么會知道,這個setTimout在for里面是異步執行的,在延遲輸出的時候,i的值已經是5了,因此會輸出 5,5,5,5,5

這個題目背后的意義在於,每隔一秒輸出i,該怎么改呢?看下面:

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

嗯,得采用閉包的方法,將里面的i值保存下來;結果就是 01234

但是如果這樣改呢?

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

我們想想,雖然有點像閉包的樣子了,但是我們需要的i的值依舊沒有傳進即時函數,沒有保持對i的引用,依舊會將i的值加到5,輸出也就是,5,5,5,5,5 。往下看

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

這一段代碼呢就是往,setTimeout里面傳入一個即時函數,傳入i,即時函數會輸出01234的,這里的效果就是不會等待1s 了,會立即輸出01234

但是在瀏覽器中會出現這么一個數字或者字符串是啥意思呢? 這是是因為定時器的 執行后會返回一個ID ,這個數字就是定時器的ID

上面用閉包的方式新手可能看不太明白,換上下面的這個;

var output = function (i) {
 setTimeout(function() {
  console.log(new Date, i);
 }, 1000);
};
 
for (var i = 0; i < 5; i++) {
 output(i); // 這里傳過去的 i 值被復制了
}
 
console.log(new Date, i);

  

 

來來,有點蒙了,小編再上最后一點代碼:

 

setTimeout(function() {
  console.log(1)
}, 0);
new Promise(function executor(resolve) {
  console.log(2);
  for( var i=0 ; i<10000 ; i++ ) {
    i == 9999 && resolve();
  }
  console.log(3);
}).then(function() {
  console.log(4);
});
console.log(5);

  Promise 的規則很簡單,就是先執行完 then 前面的函數,然后在執行then的函數,這個主要是針對回調函數的麻煩,在執行for的函數 是異步的,因此先輸出3 

下面這個promise 更好看:每隔一秒打印出來

var tasks = []; // 這里存放異步操作的 Promise
var output = (i) => new Promise((resolve) => {
 setTimeout(() => {
  console.log(new Date, i);
  resolve();
 }, 1000 * i);
});
 
// 生成全部的異步操作
for (var i = 0; i < 5; i++) {
 tasks.push(output(i));
}

  

 3.7 追加代碼筆記:es7的異步處理模式

// 模擬其他語言中的 sleep,實際上可以是任何異步操作
const sleep = (timeountMS) => new Promise((resolve) => {
 setTimeout(resolve, timeountMS);
});
 
(async () => { // 聲明即執行的 async 函數表達式
 for (var i = 0; i < 5; i++) {
  await sleep(1000);
  console.log(new Date, i);
 }
 
 await sleep(1000);
 console.log(new Date, i);
})();

 

  

每日一句:The solace of life is that each day has an end. This one will, too.

翻譯:人生值得欣慰之處便是,每一天都有結束的時候。今天亦不例外。——《星星上的人》

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM