iT邦幫忙

2022 iThome 鐵人賽

DAY 16
0
Modern Web

JS 忍者訓練計畫系列 第 16

馴服執行緒和計時器(上) Day15

  • 分享至 

  • xImage
  •  

計時器不是 JavaScript 語言的一份子,而是由網頁瀏覽器所提供物件和方法的一部分。

function timeout (fn, time) {
    let s = new Date();
    while (true) {
      if (new Date() - s >= time) {
          fn();
          break;
      }
    }
}

timeout(()=>{ console.log("haha") }, 5000)

大概是這種感覺,而發出執行請求各種事件要去執行的前後順序,Philip Roberts 在 JSConf EU 2014 的影片,聲色俱佳、並簡單清楚的講解了 event loop 的過程(還有動畫),在這裡複習一下。

這章想學到什麼?

  • 複習 eventloop (看 Philip Roberts JSConf EU 的影片)
  • 延遲 (setTimeout) 與間隔型 (setInterval) 的差異
  • 使用計時器來打斷長時任務,或 Debounce
  • 計時器中央管控

程式碼閱讀練習與撰寫

複習 eventloop (看 Philip Roberts JSConf EU 的影片)

[](https://www.youtube.com/watch?v=8aGhZQkoFbQ)

延遲 (setTimeout) 與間隔型 (setInterval) 的差異

setTimeout(funtion repeateMe(){

})

setInterval(function(){

}, 10)

使用計時器來打斷長時任務,或 Debounce

var rowCount = 20000;
var divideInto = 4;
var chunkSize = rowCount/divideInto;
var iteration = 0;

var table = document.getElementsByTagName("tbody")[0];

setTimeout(function generateRows(){
    var base = (chunkSize) * iteration;
    for (var i = 0; i < chunkSize; i++) {
        var tr = document.createElement("tr");
        for (var t = 0;t < 6; t++) {
            var td = document.createElement("td");
        td.appendChild(document.createTextNode((i + base) + "," + t + "," + iteration));
        
        tr.appendChild(td);
    }
    table.appendChild(tr);
}
iteration++;
if (iteration < divideInto)
    setTimeout(generateRows, 0);
}, 0)


//debounce 例子
function debounce(func, timeout = 300){
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => { func.apply(this, args); }, timeout);
  };
}

計時器中央管控

var timers = {
    timerID: 0,
    timers: [],
    add: function(fn){
        this.timers.push(fn)
    },
    start: function() {
        if (this.timerId) return;
        (function runNext() {
            if (timers.timers.length > 0) {
                for (var i = 0; i < timers.timers.length; i++) {
                    if(timers.timers[i]() === false) {
                        timers.timers.splice(i,1);
                        i--;
                    }
                }
                timers.timerID = setTimeout(runNext, 0);
            }
        })()
    },
    stop: function() {
        clearTimeout(this.timerID);
        this.timerID = 0;
    }
}

If you can't explain it simply, you don't understand it well enough.

參考資料

https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/EventLoop
https://www.youtube.com/watch?v=8aGhZQkoFbQ
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break


上一篇
與正規表達式吵嘴(下) Day14
下一篇
馴服執行緒和計時器(下) Day16
系列文
JS 忍者訓練計畫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言