1. 程式人生 > >Javascript定時器學習筆記

Javascript定時器學習筆記

  掌握定時器工作原理必知:JavaScript引擎是單執行緒執行的,瀏覽器無論在什麼時候都只且只有一個執行緒在執行JavaScript程式. 常言道:setTimeout和setInterval是偽執行緒。

  Javascript是執行在單執行緒環境中的,在頁面的宣告週期中,不同時間可能有其他程式碼在控制Javascript程序,比如:包含在<script>元素中的程式碼、dom元素的事件處理程式、Ajax的回撥函式。定時器僅僅是在未來的某個時刻將程式碼新增到程式碼佇列中,執行時機是不能保證的。程式碼佇列按照先進先出的原則在主程序空閒後將佇列中的程式碼交給主執行緒執行。

  

  在不同時間段內Javascript主程序處於不同狀態,開始時執行頁面中<script>元素內的程式碼,初始載入完成後,主程序進入空閒狀態,這時候有dom元素產生click事件,事件處理程式碼被新增到程式碼佇列中,程式碼佇列發現Javascript主程序處於空閒狀態,立即將佇列中的第一個元素交給主程序執行。上圖便是這一個過程的時間線。

  在Javascript中沒有任何程式碼是立刻執行的,帶一旦程序空閒則儘快執行。例如,當某個按鈕被按下時,事件處理函式會被新增到程式碼佇列中。當接收到ajax響應時,回校函式的程式碼被新增到佇列中。而定時器對佇列的工作方式是,當特定的事件過去後將程式碼加入到佇列中。

設定一個150ms後執行的定時器不代表程式碼會在150ms之後執行,而是指程式碼會在150ms後加入到程式碼佇列中。等到主程序空閒時並且該元素位於佇列首位,其中的程式碼便會立即執行,看上去好像是在精確的時間點上執行了。實際上佇列中的所有程式碼都要等到主程序空閒之後才能執行,而不管他們是怎額新增到佇列中去的。

var ele = document.getElementById('btn');
ele.onclick = function(){
    setTimeout(function(){
        document.getElementById(message).style.backgroundColor 
= "red"; }, 255); var start = Date.now(); while(Date.now() - start < 300) {}; }

  以上示例中,定時器在255ms事被插入到程式碼佇列中,但Javascript主執行緒有300ms處於執行狀態,那麼定時器程式碼至少要在定時器設定之後的300ms後才會被執行。以下時間線代表了上面程式碼的執行過程。

  重複定時器setInterval

  為了確保定時器程式碼插入到佇列總的最小間隔為指定時間。當使用setInterval()時,僅當沒有該定時器的任何其他程式碼例項時,才能將定時器程式碼新增到程式碼佇列中。假設沒有這條原則,setInterval()建立的定時器確保了定時器程式碼能夠規則的插入佇列中。那麼問題來了,假設Javascript主程序的執行時間非常長,那麼setInterval的程式碼被多次新增到了程式碼佇列中,等到主程序空閒時,定時器程式碼便會連續執行多次而之間不會有任何停頓。

  但是這條規則同樣也帶來了兩個問題:

  1. 某些間隔會被跳過
  2. 多個定時器的程式碼執行之間的間隔可能會比預期的小
var ele = document.getElementById('btn');
ele.onclick = function(){
    setInterval(function(){
    console.log('run interval');
var start = Date.now(); while(Date.now() - start < 350) {}; }, 200); var start = Date.now(); while(Date.now() - start < 300) {}; }

  以上程式碼中,click事件處理程式中通過setInterval設定了一個200ms的時間間隔的重複定時器。從以上程式碼可以看出事件處理程式花了300ms多的時間完成,而定時器程式碼也花了300ms的時間,這個時候就會出現跳過間隔且連續兩次執行定時器程式碼的情況。請看下圖:

  

  上圖中,第一個定時器在205ms出新增到佇列中的,但是直到過了300ms才能夠執行。當執行定時器程式碼時,在405ms時有一個定時器程式碼例項被新增到等待佇列中。在605ms處第一個定時器程式碼仍然在執行,同時在程式碼佇列中已經有了另一個定時器的程式碼例項。所以在這個時間點上的定時器程式碼不會被新增到佇列中。結果在205ms處新增的定時器程式碼執行完畢後,405ms處新增的定時器程式碼會立即執行。

  所以在使用setInterval做動畫時要注意兩個問題:

  1. 不能使用固定步長作為做動畫,一定要使用百分比: 開始值 + (目標值 - 開始值) * (Date.now() - 開始時間)/ 時間區間
  2. 如果主程序執行時間過長,會出現跳幀的現象

  為了避免setInterval的兩個缺點,可以使用鏈式setTimeout():

setTimeout(function(){
    //其他處理
    setTimeout(arguments.callee, interval);
}, interval);

   以上文章內容主要來自《Javascript高階程式設計》

相關推薦

Javascript定時學習筆記

  掌握定時器工作原理必知:JavaScript引擎是單執行緒執行的,瀏覽器無論在什麼時候都只且只有一個執行緒在執行JavaScript程式. 常言道:setTimeout和setInterval是偽執行緒。   Javascript是執行在單執行緒環境中的,在頁面的宣告週期中,不同時間可能有其他程式碼在控

STM32 通用定時定時功能 學習筆記

這節主要講下STM32 通用定時器的定時功能。 一、TIMx的時鐘源問題: STM32有8路暫存器,包括TIM1和TIM8兩個高階定時器,TIM6和TIM7兩個基本定時器,TIM2-TIM5四個通用定時器,定時器是完全獨立的,而且沒有互相共享任何資源,它們可以一起同步操作,

頂點著色 學習筆記

裁剪 str cati strong log href open rotate 程序 頂點著色器 shader的三種變量類型 uniform變量一般用來表示:變換矩陣,材質,光照參數和顏色等信息;如果在vertex和fragment兩者之間聲明方式完全一樣,則它可以在v

javascript-定時

定時器一、時鐘:<!doctype html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <style> #div1 {back

ArcGIS API for JavaScript 4.4學習筆記[新] AJS4.4和AJS3.21新特性

ack 讀取 port 不同 ide evel arc ges wfs ESRI官網悄無聲息突然更新4.4和3.21,公眾號也沒有什麽消息。照例,給大家看看這次更新有什麽新特性吧。 1. AJS 4.4 官方更新日誌:點我,比較詳細。我在這裏抽一些主幹作為說明。 1.1

Windows定時學習

內核對象 arm 三個參數 inf ont 多少 defined win int 定時器是一個在特定時間或者規則間隔被激發的內核對象。結合定時器的異步程序調用可以允許回調函數在任何定時器被激發的時候執行。 通過調用CreateWaitableTimer()可以創建一個定時器

JavaScript 30 - 2 學習筆記

hand 1.7 tin top 直接 ref 圓心 同時 獲取 學習JavaScirpt30的筆記! 有意思! 2-------> CSS clock 效果是這樣的.... 這是改良過後的 版本.... 話不多說,直接來看代碼。 首先是html部分 &l

Kestrel Web 服務學習筆記

tabpanel 簡單的 事件循環 請求 eat 線程池。 hub .cn 封裝庫 前言:   ASP.NET Core 已經不是啥新鮮的東西,很多新啟的項目都會首選 Core 做開發;   而 Kestrel 可以說是微軟推出的唯一真正實現跨平臺的 Web 服務器了;

JavaScript定時 setTimeout與setInterval 淺析

throttle tin 並不是 tint 導致 語句 運行 應用 超過 一、 前情提要   1)JavaScript 是運行在單線程的執行環境中的   2)由瀏覽器安排事件的執行順序 二、setTimeout   使用場景: 設定代碼在未來的某個時間執行,而執行的時機是不

JavaScript作用域學習筆記

execution 代碼 函數 asc 後臺 glob 全局 ref java 文章部分實例和內容來自鳥哥的blogJavascript作用域原理 在JS中,作用域的概念和其他語言差不多,是JS中一個極為重要的概念。在每次調用一個函數的時候 ,就會進入一個函數內的作用域,當

《你不知道的 JavaScript 上卷》 學習筆記

步驟 查找 分詞 類初始化 之間 加強 定時器 屬於 gif 第一部分: 作用域和閉包 一、作用域 1. 作用域:存儲並查找變量的規則 2. 源代碼在執行之前(編譯)會經歷三個步驟: 分詞/此法分析:將代碼字符串分解成有意義的代碼塊(詞法單元) 解析/語法分析

Java類加載學習筆記

xtend 讀取 instance DC over null urn loader not 今後一段時間會全面讀一下《深入理解Java虛擬機》 在這裏先記一下在網上看到的幾篇介紹 類加載器 的文章,等讀到虛擬機類加載機制再詳細介紹。 超詳細Java中的ClassLoader

JavaScript定時

語句 ssa clear 引用 element oat cap border width JavaScript定時器恢復 Windows對象包含了4個定時器方法,說明如下表所示: Windows對象定時器方法列表 方法 說明 setTim

java計時學習筆記

read pre () pub run 指定 執行 exception rup /** * @param args * @throws InterruptedException */ public static void main(S

JavaScript核心技術學習筆記(1)——DOM基礎

無法 strong 元素節點 tor cli val 獲取元素 是什麽 標準 DOM基礎 一、DOM是什麽   Document object Model,文檔對象模型,是由W3C定義的一個標準。簡單來說,DOM裏面有很多方法,我們通過它提供的方法來操作一個頁面中的某個元素

JavaScript核心技術學習筆記(2)——DOM基礎(2)

轉換 替換元素 沒有 ack true html中 事件 想要 dom基礎 DOM基礎(2) 一、插入元素 上一篇文章中我們學會了如何創建元素,但僅僅是創建一個元素而沒有插入到HTML中,這是沒有意義的。插入元素有以下兩種方法: ? appendChild() ? inse

JavaScript核心技術學習筆記(4)——事件基礎

() block 發生 UNC spa on() strong 1.2 type 事件基礎 一、事件 事件是什麽? 舉個例子,我們在點擊一個按鈕時,會彈出一個對話框。其中,“點擊”就是一個事件,“彈出對話框”就是我們在點擊這個事件後發生的動作。 在JS中,一個事件應該有三個

JavaScript定時實現背景顏色交替變換

style doctype .get code c函數 idt 設置 eight remove 原生JavaScript定時器實現背景顏色交替變換 <!DOCTYPE html> <html lang="zh-cn"> <head&g

javascript權威指南--學習筆記

-一、JavaScript基本資料型別 1、數字--Number類 2、字串--String類 3、布林--Boolean類 4、函式Function 5、物件Object 6、陣列Array 7、null 8、undefined 備註:    當一個未定義的值用於布林環

CSS 選擇學習筆記

CSS常用選擇器 1 元素選擇器 標籤選擇器 p {color:gray;} h2 {color:silver;} p h2 都是元素標籤   2 類選擇器  .className   3 ID選擇器 #ID &