當前位置:
首頁 > 最新 > 管理頁面的 setTimeout&setInterval

管理頁面的 setTimeout&setInterval

來源:凹凸實驗室

aotu.io/notes/2017/09/25/manage-setTimeout-an-setInterval/

在管理 setTimeout & setInterval 這兩個 APIs 時,筆者通常會在頂級(全局)作用域創建一個叫 timer 的對象,在它下面有兩個數組成員 —— ,用它們來分別存儲需要管理的 setTimeoutID / setIntervalID。如下:

vartimer={

sto:[],

siv:[]

};

在使用 setTimeout / setInterval 的時候,這樣調用:

// 標記 setTimeoutID

setTimeout(function(){console.log("3s")},3000);

);

// 標記 setIntervalID

setInterval(function(){console.log("1s")},1000)

);

在頁面需要 clearTimeout clearInterval 的時候,這樣調用:

// 批量清除 setTimeout

// 批量清除 setInterval

暫停 & 恢復

近段時間,筆者發現很多業務都需要「暫停」和「恢復」setTimeout & setInterval 的功能,而僅靠原生的四個 APIs(setTimeout / setIntervale / clearTimeout / clearInterval)是不夠用的。於是,筆者對 timer 進行了擴展,使它具備了「暫停」和「恢復」的功能,如下:

// 暫停所有的 setTimeout & setInterval

timer.pause();

// 恢復所有的 setTimeout & setInterval

timer.resume();

擴展後的 timer對象下面掛載6個基礎的 APIs。

setTimeout

setInterval

clearTimeout

clearInterval

pause

resume

使用 timer.set* & timer.clear* 來代替原生的 set* & clear*。筆者把擴展後的 timer 託管在 GitHub 倉庫上,有興趣的同學可以移步:https://github.com/leeenx/timer

CreateJS 的啟發

在使用 CreateJS 開發一些項目的過程中,筆者發現通過設置 createjs.Ticker.paused = true / false,可以暫停/恢復 createjs.Tween 上的動畫。於是筆者借用 createjs.Tween 模擬了 setTimeout & setInterval 的功能,如下:

// setTimeout

createjs.setTimeout=function(fn,delay){

createjs.Tween.get().wait(delay).call(fn);

}

//setInterval

createjs.setInterval=function(fn,delay){

createjs.Tween.get().wait(delay).call(fn).loop=1;

}

具體的代碼筆者託管在:createjs.timer(https://github.com/leeenx/createjs.timer)。

其實就是在 createjs 對象下掛載四個 APIs:

setTimeout

setInterval

clearTimeout

clearInterval

使用方法與原生的 setTimeout & setInterval 一樣,如下:

letsiv=createjs.setInterval(()=>console.log("1s"),1000);

createjs.setTimeout(()=>createjs.clearInterval(siv),5000);

時間軸驅動的 timer

createjs.timer 在 CreateJS 項目的開發給筆者帶來了極大的便利,但是它必須依賴 createjs.Tween 模塊。於是筆者就在思考能否創建一個跟第三方框架無關並且又可以在第三方框架上使用的 timer。

createjs.Ticker.paused 為什麼能暫停 createjs.Tween 上的動畫的?

createjs.Tween 中每一個動畫都有一條自己的時間軸,這條時間軸是通過 createjs.Ticker 來驅動的;當 createjs.Ticker 被暫停後,createjs.Tween 中的每個動畫的時間軸也會失去動力而暫停下來。

createjs.Ticker 的作用是提供一個刷新 canvas 畫面幀頻,通常是使用 requestAnimationFrame or setInterval 來實現的。如果 timer 內部存在一條時間軸,這條時間軸由第三方驅動,那麼 timer 就可以與第三方框架狀態同步了。

筆者是這樣設計 timer 的結構:

queue —— 存放 setTimeout or setInterval 的隊列;

updateQueue —— 驅動 queue 的內部 API;

update —— 外部介面,用於對接第三方 Ticker。

實現的偽代碼如下:

/*

@queue 成員的結構如下:

{

fn: fn, // 回調函數

type: "timeout or interval", // 類型

elapsed: 0, // 時間軸進度

delay: delay // 目標時長

}

*/

letqueue=newMap();

functionupdateQueue(delta){

queue.forEach((item,id)=>{

item.elapsed+=delta;

if(item.elapsed>=item.delay){

item.fn();

// 從 queue 中刪除 setTimeout 成員,interval 成員繼續循環

item.type==="timeout"?delete(id):(item.elapsed=);

}

});

}

// 對外介面

this.update=function(delta){

updateQueue(delta);

}

timer 的具體實現可以參考:https://github.com/leeenx/es6-utils#timer

timer 與 CreateJS 一起使用:

// es6 代碼

import timerfrom ./modules/timer ;

// 統一 ticker

createjs.Ticker.addEventListener("tick",function(e){

e.pausedtimer.update(e.delta);

});

timer 與 PIXI 一起使用:

// es6 代碼

import timerfrom ./modules/timer ;

// 統一 ticker

app.ticker.add("tick",function(){

timer.update(app.ticker.elapsedMS);

});

附上 PIXI 的線上 DEMO,二維碼如下:

總結

感謝閱讀完本文章的讀者。本文僅代表個人觀點,希望能幫助到有相關問題的朋友,如果本文有不妥之處請不吝賜教。

看完本文有收穫?請轉發分享給更多人

關注「前端大全」,提升前端技能


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 前端大全 的精彩文章:

為什麼我們要做三份 Webpack 配置文件
Web 的現狀:網頁性能提升指南
你知道URL、URI和URN三者之間的區別嗎?
V8 內存分配與垃圾回收
2000塊都沒人的蘋果SE

TAG:前端大全 |