成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

菜鳥理解setTimeout和setInterval

sixleaves / 3100人閱讀

摘要:也就是說,這僅僅是計(jì)劃在未來某一個(gè)時(shí)間執(zhí)行某個(gè)任務(wù),并不能保證精確的時(shí)間。重復(fù)執(zhí)行問題這個(gè)方法執(zhí)行時(shí)僅當(dāng)沒有該計(jì)時(shí)器的其他代碼示例時(shí)才進(jìn)行下一輪的執(zhí)行。這樣的規(guī)則就會(huì)導(dǎo)致某些間隔會(huì)被跳過,同時(shí)多個(gè)間隔可能比預(yù)期時(shí)間要短。

寫在前面,最近在準(zhǔn)備校招,陸陸續(xù)續(xù)做一些之前的總結(jié),寫了一個(gè)小系列的文章,想借此機(jī)會(huì)記錄下來,也能以后有個(gè)地方能進(jìn)行查閱,上一篇文章在css基礎(chǔ)總結(jié)希望能幫助一下和我一樣的菜鳥們好了,正文開始。

這是一個(gè)老生常談,新手掉坑的問題,算是一個(gè)比較經(jīng)典的對(duì)于javascript運(yùn)行機(jī)制的理解問題,我在這里粗淺的談一下自己的理解,話不多說,進(jìn)入正題:

兩者表面上的區(qū)別

setTimeout() 方法用于在指定毫秒數(shù)之后調(diào)用其中的函數(shù)

setInterval() 方法則是在間隔一定毫秒后重復(fù)調(diào)用其中的函數(shù)

透過現(xiàn)象看本質(zhì) 時(shí)間精確問題

由于js是運(yùn)行在單線程的環(huán)境當(dāng)中的,單線程就意味著任務(wù)的執(zhí)行需要依賴任務(wù)隊(duì)列。實(shí)際運(yùn)行時(shí)是將兩個(gè)方法的代碼塊移出當(dāng)前運(yùn)行環(huán)境(從任務(wù)隊(duì)列移出到回調(diào)隊(duì)列中),當(dāng)執(zhí)行完當(dāng)前任務(wù)后,檢查回調(diào)隊(duì)列中有無需要執(zhí)行的任務(wù)(對(duì)應(yīng)這兩個(gè)方法為是否已經(jīng)到執(zhí)行時(shí)間),可是如果時(shí)間到時(shí)恰好有別的任務(wù)在進(jìn)行的話,由于其單線程的機(jī)制,該方法就只能等到當(dāng)前任務(wù)結(jié)束之后才能運(yùn)行。

回到方法本身,這就相當(dāng)于其他的正常任務(wù)在一個(gè)隊(duì)列中,當(dāng)遇到這兩個(gè)方法時(shí),就將他們移出隊(duì)列,并開始計(jì)時(shí),當(dāng)時(shí)間到時(shí),直接“插隊(duì)”到隊(duì)首,如果隊(duì)首有正在執(zhí)行的任務(wù),則排在次隊(duì)首,等待執(zhí)行。也就是說,這僅僅是“計(jì)劃”在未來某一個(gè)時(shí)間執(zhí)行某個(gè)任務(wù),并不能保證精確的時(shí)間。

setInterval重復(fù)執(zhí)行問題

這個(gè)方法執(zhí)行時(shí)僅當(dāng)沒有該計(jì)時(shí)器的其他代碼示例時(shí)才進(jìn)行下一輪的執(zhí)行。這樣的規(guī)則就會(huì)導(dǎo)致某些間隔會(huì)被跳過,同時(shí)多個(gè)間隔可能比預(yù)期時(shí)間要短。所以為了避免setInterval所造成的問題,可以用setTimeout來通過循環(huán)代替setInterval方法,從而實(shí)現(xiàn)一個(gè)重復(fù)的定時(shí)器(除非必要,盡量避免代碼中出現(xiàn)setInterval)

方法中使用this的問題

在兩個(gè)方法中傳入函數(shù)時(shí)(即第一個(gè)函數(shù)參數(shù)中含有另外一個(gè)函數(shù)),此函數(shù)中的this會(huì)只想window對(duì)象。這是由于兩個(gè)方法調(diào)用的代碼在與所在函數(shù)完全分離的執(zhí)行環(huán)境上(第一條中有講到的兩個(gè)方法的運(yùn)行機(jī)制),這就會(huì)導(dǎo)致這些代碼中包含的this關(guān)鍵字會(huì)指向window(或全局)對(duì)象。

但是要注意,如果this只是在兩個(gè)方法中而不是在方法中的函數(shù)中時(shí),this的指向符合我們的預(yù)期為當(dāng)前對(duì)象。

解決方法:

1.將當(dāng)前對(duì)象的this存為一個(gè)變量,定時(shí)器內(nèi)的函數(shù)利用閉包來訪問這個(gè)變量,如下:

var num = 0;
function Obj (){
    var that = this;    //將this存為一個(gè)變量,此時(shí)的this指向obj
    this.num = 1,
    this.getNum = function(){
        console.log(this.num);
    },
    this.getNumLater = function(){
        setTimeout(function(){
            console.log(that.num);    //利用閉包訪問that,that是一個(gè)指向obj的指針
        }, 1000)
    }
}
var obj = new Obj;
obj.getNum();          //1  打印的為obj.num,值為1
obj.getNumLater()      //1  打印的為obj.num,值為1

2.利用bind()方法:

var num = 0;
function Obj (){
    this.num = 1,
    this.getNum = function(){
        console.log(this.num);
    },
    this.getNumLater = function(){
        setTimeout(function(){
            console.log(this.num);
        }.bind(this), 1000)    //利用bind()將this綁定到這個(gè)函數(shù)上
    }
}
var obj = new Obj;
obj.getNum();                 //1  打印的為obj.num,值為1
obj.getNumLater()             //1  打印的為obj.num,值為1

bind()方法是在Function.prototype上的一個(gè)方法,當(dāng)被綁定函數(shù)執(zhí)行時(shí),bind方法會(huì)創(chuàng)建一個(gè)新函數(shù),并將第一個(gè)參數(shù)作為新函數(shù)運(yùn)行時(shí)的this。在這個(gè)例子中,在調(diào)用setTimeout中的函數(shù)時(shí),bind方法創(chuàng)建了一個(gè)新的函數(shù),并將this傳進(jìn)新的函數(shù),執(zhí)行的結(jié)果也就是正確的了。關(guān)于bind方法可參考 MDN bind

清除計(jì)時(shí)器 clearTimeout()

在在使用setTimeout時(shí),該方法會(huì)返回一個(gè)唯一的關(guān)于當(dāng)前計(jì)時(shí)器的計(jì)時(shí)ID,在clearTimeout()方法中傳入這個(gè)ID值即可取消對(duì)應(yīng)的Timeout

clearInterval()

同上

參考

上面是我在使用過程中遇到問題后在網(wǎng)上查閱后自己的一些總結(jié),希望對(duì)和我一樣的新手有所幫助,想要更深入了解他們的區(qū)別和js的一些運(yùn)行機(jī)制,請(qǐng)入傳送門:

傳送門1---阮大的剖析

傳送門2---this指向

傳送門3---調(diào)用執(zhí)行


文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/84222.html

相關(guān)文章

  • 前端校招準(zhǔn)備系列--js中的setTimeout到底是什么?

    摘要:瀏覽器是多進(jìn)程的,而瀏覽器的內(nèi)核渲染進(jìn)程是多線程的。如果已經(jīng)將回調(diào)函數(shù)放進(jìn)任務(wù)隊(duì)列,但是主線程正在執(zhí)行一個(gè)非常耗時(shí)的任務(wù),當(dāng)這個(gè)任務(wù)執(zhí)行完畢后,主線程去任務(wù)隊(duì)列中取任務(wù),這個(gè)時(shí)候,就會(huì)出現(xiàn)連續(xù)執(zhí)行的情況,也就是說相當(dāng)于失效了。 前言 ??在刷筆試題的時(shí)候,經(jīng)常會(huì)碰到setTimeout的問題,只知道這個(gè)是設(shè)置定時(shí)器;但是考察的重點(diǎn)一般是在一個(gè)方法中包含了定時(shí)器,定時(shí)器中的打印和方法中打...

    Godtoy 評(píng)論0 收藏0
  • Javascript學(xué)習(xí)總結(jié) - JS基礎(chǔ)系列三

    摘要:案例每隔毫秒調(diào)用函數(shù)并顯示時(shí)間。當(dāng)點(diǎn)擊按鈕時(shí),停止時(shí)間代碼如下計(jì)時(shí)器每隔毫秒調(diào)用函數(shù),并將返回值賦值給計(jì)時(shí)器計(jì)時(shí)器,在載入后延遲指定時(shí)間后去執(zhí)行一次表達(dá)式僅執(zhí)行一次。該值標(biāo)識(shí)要取消的延遲執(zhí)行代碼塊。 簡述 本系列將持續(xù)更新Javascript基礎(chǔ)部分的知識(shí),誰都想掌握高端大氣的技術(shù),但是我覺得沒有一個(gè)扎實(shí)的基礎(chǔ),我認(rèn)為一切高階技術(shù)對(duì)我來講都是過眼云煙,要成為一名及格的前端工程師,必須把...

    zlyBear 評(píng)論0 收藏0
  • JS事件循環(huán),了解一下

    摘要:任務(wù)隊(duì)列中的代碼被加載到函數(shù)調(diào)用棧中去執(zhí)行。說到這里,你基本上對(duì)事件循環(huán)有個(gè)大致的了解了。 在理解事件循環(huán)之前,我總會(huì)遇到一些奇奇怪怪的問題:比如明明已經(jīng)調(diào)接口拿到了數(shù)據(jù),可是跟在調(diào)數(shù)據(jù)之后的操作卻沒有正常執(zhí)行;又或者不知道為啥,代碼里非得加個(gè)setTimeout才能正常跑通;特別是在運(yùn)用Promise的時(shí)候,更是有各種問題百思不得解。遇上問題要解決,更要知道問題產(chǎn)生的原因,這樣才能h...

    xbynet 評(píng)論0 收藏0
  • setTimeoutsetInterval

    摘要:一個(gè)頁面在瀏覽器顯示出來至少需要個(gè)線程,分別是引擎,渲染,事件觸發(fā)。其中事件觸發(fā)是獨(dú)立于其他個(gè)執(zhí)行的,而和是相互排斥的,也就是說同一個(gè)時(shí)間二者只有一個(gè)在工作。 作為DOM本身十分重要的2個(gè)異步執(zhí)行函數(shù),初學(xué)者感覺這個(gè)很不好理解,我簡單寫一寫我的理解 setTimeout (func, millisec); setInterval(func, millisec); 這兩個(gè)方法在形式看起來...

    SnaiLiu 評(píng)論0 收藏0
  • 理解javascript中的事件循環(huán)(Event Loop)

    摘要:主線程會(huì)暫時(shí)存儲(chǔ)等異步操作,直接向下執(zhí)行,當(dāng)某個(gè)異步事件觸發(fā)時(shí),再通知主線程執(zhí)行相應(yīng)的回調(diào)函數(shù),通過這種機(jī)制,避免了單線程中異步操作耗時(shí)對(duì)后續(xù)任務(wù)的影響。 背景 在研究js的異步的實(shí)現(xiàn)方式的時(shí)候,發(fā)現(xiàn)了JavaScript 中的 macrotask 和 microtask 的概念。在查閱了一番資料之后,對(duì)其中的執(zhí)行機(jī)制有所了解,下面整理出來,希望可以幫助更多人。 先了解一下js的任務(wù)執(zhí)...

    mykurisu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<