




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第js實現(xiàn)0ms延時定時器的幾種方式目錄queueMicrotask
async/await
MessageChannel
最后
附錄
這兩天看到一篇介紹《如何實現(xiàn)準(zhǔn)時的setTimeout?》的文章,文章起源于一道面試題:有什么辦法讓setTimeout準(zhǔn)時呀?具體文章內(nèi)容可查看附錄【1】,看完之后,引起了我對setTimeout這個函數(shù)的探究興趣,因此在MDN上重新查閱了相關(guān)文檔,其中提到【最小延時=4ms】的一點,因此使用setTimeout不能實現(xiàn)0ms延時的定時器,如果要實現(xiàn)的話,提供了一個參考鏈接【2】,作者的實現(xiàn)思路是通過postMessage來模擬,繞過setTimeout的限制,從而實現(xiàn)0ms延時的定時器,說簡單來講就是起了一個宏任務(wù)去執(zhí)行回調(diào),先具體看下是怎么實現(xiàn)的:
(function(){
vartimeouts=[];
varmessageName="zero-timeout-message";
//LikesetTimeout,butonlytakesafunctionargument.There's
//notimeargument(alwayszero)andnoarguments(youhavetouseaclosure)
functionsetZeroTimeout(fn){
timeouts.push(fn);
window.postMessage(messageName,"*");
functionhandleMessage(event){
if(event.source==windowevent.data==messageName){
event.stopPropagation();
if(timeouts.length0){
varfn=timeouts.shift();
fn();
window.addEventListener("message",handleMessage,true);
//Addtheonethingwewantaddedtothewindowobject.
window.setZeroTimeout=setZeroTimeout;
})();
作者還提供了一個demo頁面【3】,通過于setTimeout(0)進(jìn)行對比,在我瀏覽器的執(zhí)行結(jié)果如下:
100iterationsofsetZeroTimeouttook15milliseconds.
100iterationsofsetTimeout(0)took488milliseconds.
根據(jù)結(jié)果對比來看,setZeroTimeout執(zhí)行比setTimeout快了上百倍,這是一個巨大的提升。今天想討論的是除了上述這種方式,還可以通過哪些方式來實現(xiàn)一個0ms延時的定時器呢,首先,我們要確定一下我們自定義的定時器是異步的,其次是盡可能早的被執(zhí)行。說起異步,js提供了好幾種解決方案,我們可以逐一去驗證。
在深入討論各種實現(xiàn)方式之前,約定提供的setTimeout對比版本如下,后面自定義實現(xiàn)的方案都將和setTimeout版本的執(zhí)行時間進(jìn)行對比,代碼比較簡單:
(function(){
leti=0;
conststart=Date.now();
functiontest(){
if(i++100){
setTimeout(test);
}else{
console.log('setTimeout執(zhí)行時間:',Date.now()-start);
setTimeout(test);
})();
queueMicrotask
queueMicrotask這個api可以添加一個微任務(wù),使用比較簡單,直接傳遞一個回調(diào)函數(shù)即可,具體實現(xiàn)如下:
(function(){
functionsetZeroTimeout(fn){
queueMicrotask(fn);
leti=0;
conststart=Date.now();
functiontest(){
if(i++100){
setZeroTimeout(test);
}else{
console.log('setZeroTimeout執(zhí)行時間:',Date.now()-start);
setZeroTimeout(test);
})();
通過和setTimeout版本進(jìn)行對比,最終結(jié)果如下:
setZeroTimeout執(zhí)行時間:2
setTimeout執(zhí)行時間:490
關(guān)于這個API的介紹在MDN上有詳細(xì)的說明,就不展開介紹了,這里多說一點,根據(jù)規(guī)范文檔的說明,大多數(shù)情況下,推薦使用requestAnimationFrame()和requestIdleCallback()等api,因為queueMicrotask會阻塞渲染,在很多時候都不是一種好的實踐。
async/await
async/await對于前端開發(fā)人員來說已經(jīng)是必不可少的了,這里我們也可以用來實現(xiàn):
(function(){
asyncfunctionsetAsyncTimeout(fn){
Promise.resolve().then(fn);
leti=0;
conststart=Date.now();
asyncfunctiontest(){
if(i++100){
awaitsetAsyncTimeout(test);
}else{
console.log('setAsyncTimeout執(zhí)行時間:',Date.now()-start);
setAsyncTimeout(test);
})();
通過和setTimeout版本進(jìn)行對比,最終結(jié)果如下:
setAsyncTimeout執(zhí)行時間:2
setTimeout執(zhí)行時間:490
如果不嫌麻煩,還可以通過Promise來實現(xiàn),其實都是大同小異,無非多些點代碼,這里就省略了。
MessageChannel
MessageChannel允許我們創(chuàng)建一個新的消息通道,并通過它的兩個MessagePort屬性發(fā)送數(shù)據(jù),MessageChannel提供端口的概念,實現(xiàn)端口之間的通信,比如worker/iframe之間的通信。
(function(){
constchannel=newMessageChannel();
functionsetMessageChannelTimeout(fn){
channel.port2.postMessage(null);
channel.port1.onmessage=function(){
test();
leti=0;
conststart=Date.now();
functiontest(){
if(i++100){
setMessageChannelTimeout(test);
}else{
console.log('setMessageChannelTimeout執(zhí)行時間:',Date.now()-start);
setMessageChannelTimeout(test);
})();
通過和setTimeout版本進(jìn)行對比,最終結(jié)果如下:
setMessageChannelTimeout執(zhí)行時間:4
setTimeout執(zhí)行時間:490
第三種方式運行時間比前面兩種更長些,因為通過MessageChannel產(chǎn)生的是宏任務(wù),其他兩種是微任務(wù),微任務(wù)執(zhí)行靠前,且會阻塞主線程
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 公寓多層轉(zhuǎn)讓合同范例
- 三人合資合同范例
- 公司合作投標(biāo)協(xié)議合同范例
- 中央空調(diào)改造合同范例
- 公司運營權(quán)合同范例
- 講解復(fù)習(xí)要點的工程師認(rèn)證試題及答案
- 2024年初級審計準(zhǔn)備必讀書籍試題及答案
- 付款無合同范例
- 產(chǎn)品買賣購銷合同范例
- 天然氣巡檢記錄表
- 金丹生物新材料有限公司年產(chǎn)7.5萬噸聚乳酸生物降解新材料項目環(huán)境影響報告書
- (完整版)離婚協(xié)議書
- 養(yǎng)老院工作人員保密協(xié)議書
- 五年級數(shù)學(xué)下冊《圖形的運動》課件
- 數(shù)據(jù)網(wǎng)-IPRAN含IPRAN基礎(chǔ)組網(wǎng)和IPRAN高級知識
- 上市公司執(zhí)行企業(yè)會計準(zhǔn)則案例解析-中國證監(jiān)會會計部編
- 2023年副主任醫(yī)師(副高)-中醫(yī)婦科學(xué)(副高)考試上岸拔高歷年高頻考點真題含答案
- 2023年高級政工師理論考試題庫大全-下(多選600多題)
- 民間游戲課件完整版
- 梨山老母玄妙真經(jīng)
評論
0/150
提交評論