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

資訊專欄INFORMATION COLUMN

關(guān)于 setTimeout 與 setInterval,你需要知道的一切

rottengeek / 593人閱讀

摘要:這里是結(jié)論,將是更驚艷的那一個。瀏覽器隔一段時間像服務(wù)器發(fā)送一個請求,詢問這里有沒有需要更新的消息。在響應(yīng)回來時,才會繼續(xù)發(fā)出第二個請求。但是,顯然的,這對我們要做的事來說并不算是什么問題。

我們都知道的是setTimout是用來延遲一個簡單的動作的,然而,setInterval的目的是用來重復(fù)執(zhí)行某個動作的。

然后,以上只是一半的事實。因為如果一個函數(shù)需要在一個間隔時間內(nèi)重復(fù)的執(zhí)行,你也可以輕松的使用 setTimeout 設(shè)定延遲時間,被延遲執(zhí)行的函數(shù)再進(jìn)行自調(diào)用以此實現(xiàn)循環(huán)。

所以,這里有2種方法做同樣的事

一個用setInterval

var doStuff = function () {
  // Do stuff
};
setInterval(doStuff, 1000);

一個用setTimeout

var doStuff = function () {
    // DoStuff
    setTimeout(doStuff, 1000); 
};
setTimeout(doStuff, 1000);
// 如果你想立即執(zhí)行函數(shù),可以這樣寫
var doStuff = function () {
    setTimeout(doStuff, 1000);
}
doStuff();
// 或者,更酷的方式,使用立即執(zhí)行函數(shù)
(function doStuff () {
   // Do Stuff
   setTimeout(doStuff, 1000);
}())

這必然導(dǎo)致下面兩個問題

問題:setInterval和self-invoking setTimeout-loops是可以互相替換的嗎?
答案:不,當(dāng)然不行。它們之間有著很細(xì)微的區(qū)別,但是如果想寫出好的代碼,這些細(xì)微的區(qū)別便是你想知道的事。

當(dāng)然,接下我將會訴說的,第一,我將告訴你,我們通常會遇到什么樣的問題,第二,我將開始介紹它們之間細(xì)微的區(qū)別,這些區(qū)別將讓我們從這兩個選擇中選出更具吸引力的那個一,第三,我將告訴你其實根本不用關(guān)心另一個。然后。這里是結(jié)論,setTimeout將是更驚艷的那一個。接下來我將一點一點解釋。

進(jìn)程堵塞

首先:如果你試著重復(fù)調(diào)用的函數(shù)并不會化太多的時間來跑,那么將不會有任何問題。即使如此,被調(diào)用的函數(shù)依然會出現(xiàn)2中不同的情況:它既可以在CPU上高集中的運(yùn)行腳本,或者它也可以在腳本流外先發(fā)出一個命令,并等待結(jié)果的到來。

我們主要研究先看第二種情況。典型的便是ajax回調(diào):你的腳本并不會等待服務(wù)器的響應(yīng),它會自己執(zhí)行到最后,并讓回調(diào)函數(shù)來監(jiān)聽ajax響應(yīng)。

現(xiàn)在,一些網(wǎng)站想要你保持實時更新,像Gmail,當(dāng)你獲得一封新的郵件時便會刷新你的郵箱。這里服務(wù)端有新消息時便實時通知瀏覽器端的技術(shù),通常叫做ajax輪詢。瀏覽器隔一段時間像服務(wù)器發(fā)送一個請求,詢問這里有沒有需要更新的消息。

你也許會想,你很擅長使用setInterval

// 不要這樣做
var pollServerForNewMail = function () {
  $.getJSON("/poll_newmail.php", function (response) {
    if (response.newMail) {
      alert(
        "New mail. At last. You made me walk all the way to the server and back every " +
        "second for this, so if this isn"t life-or-death, you got another thing coming."
      );
    }
  });
};
setInterval(pollServerForNewMail, 1000);

其實像上面那樣寫并不好。因為請求發(fā)送出去到回來是需要時間的,但是這段時間誰能保證會比你設(shè)置的間隔時間要短呢?

一個典型的初學(xué)者的錯誤,會想將輪詢的間隔時間設(shè)置的長一點也許可以解決這個問題。然后,事實是,無論你的間隔時間設(shè)的是多少,它依然有可能比,ajax響應(yīng)的時間短。也就是說,有可能會發(fā)生,第一個請求還沒回來的情況下,第二請求又已經(jīng)發(fā)出去了。而你需要的是兩個請求之間有呼吸的空間,而setTimeout便可以解決這個問題。

(function pollServerForNewMail() {
  $.getJSON("/poll_newmail.php", function (response) {
    if (response.newMail) {
      alert(
        "You have received a letter, good sir. " + 
        "I will have a quick lie-down and be on my way shortly."
      );
    }
    setTimeout(pollServerForMail, 1000);
  });
}());

在第一次發(fā)出請求,服務(wù)器響應(yīng)之前,不會發(fā)生任何事。在響應(yīng)回來時,才會繼續(xù)發(fā)出第二個請求。當(dāng)然,這也就意味著,兩個輪詢之間的時間超過了1秒,這也依賴于各種各樣的因素,像網(wǎng)速和服務(wù)器的響應(yīng)速度等。但是,顯然的,這對我們要做的事來說并不算是什么問題。

例子

這里有兩個例子來更好的進(jìn)行說明。

var timesRun = 0;
var startTime = new Date().getTime();

var doStuff = function () {
  var now = new Date().getTime();

  // 只跑5次
  if (++timesRun == 5) clearInterval(timer);

  console.log("Action " + timesRun + " started " + (now - startTime) + "ms after script start");

  // Waste some time
  for (var i = 0; i < 100000; i++) {
    document.getElementById("unobtanium");
  }

  console.log("and took " + (new Date().getTime() - now) + "ms to run.");
};

var timer = setInterval(doStuff, 1000);

下面是結(jié)果

Action 1 started 1000ms after script start
and took 8ms to run.
Action 2 started 2000ms after script start
and took 8ms to run.
Action 3 started 3004ms after script start
and took 6ms to run.
Action 4 started 4002ms after script start
and took 6ms to run.
Action 5 started 5000ms after script start
and took 6ms to run.

這里并沒有多大的意外。這段代碼中間的循環(huán)花了一點時間,但是setInterval依然很嚴(yán)格的執(zhí)行了它的計劃。在一秒的間隔之間,開始時間之間并沒有一點空隙。

現(xiàn)在是setTimeout-loop的例子

var timesRun = 0;
var startTime = new Date().getTime();

var doStuff = function () {
  var now = new Date().getTime();

  console.log("Action " + (timesRun + 1) + " started " + (now - startTime) + "ms after script start");

  // Waste some time
  for (var i = 0; i < 100000; i++) {
    document.getElementById("unobtanium");
  }

  console.log("and took " + (new Date().getTime() - now) + "ms to run.");

  // Run only 5 times
  if (++timesRun < 5) {
    setTimeout(doStuff, 1000);
  }
};

setTimeout(doStuff, 1000);

輸出結(jié)果

Action 1 started 1010ms after script start
and took 8ms to run.
Action 2 started 2021ms after script start
and took 8ms to run.
Action 3 started 3031ms after script start
and took 5ms to run.
Action 4 started 4037ms after script start
and took 6ms to run.
Action 5 started 5043ms after script start
and took 6ms to run.

這里也并沒有太多的意外。我們已經(jīng)知道setTimeout-loop并不會嚴(yán)格的執(zhí)行計劃,而是在函數(shù)下一次調(diào)用之前,會給函數(shù)它足夠的時間執(zhí)行它里面的代碼。

結(jié)論

不要使用setInterval,如果你在乎你的時間。setTimeout-loop可以給你足夠的時間控制你的腳本和回調(diào),

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

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

相關(guān)文章

  • 徹底弄懂 JavaScript 執(zhí)行機(jī)制

    摘要:關(guān)于這部分有嚴(yán)格的文字定義,但本文的目的是用最小的學(xué)習(xí)成本徹底弄懂執(zhí)行機(jī)制,所以同步和異步任務(wù)分別進(jìn)入不同的執(zhí)行場所,同步的進(jìn)入主線程,異步的進(jìn)入并注冊函數(shù)。宏任務(wù)微任務(wù)第三輪事件循環(huán)宏任務(wù)執(zhí)行結(jié)束,執(zhí)行兩個微任務(wù)和。 不論你是javascript新手還是老鳥,不論是面試求職,還是日常開發(fā)工作,我們經(jīng)常會遇到這樣的情況:給定的幾行代碼,我們需要知道其輸出內(nèi)容和順序。 因為javascr...

    gyl_coder 評論0 收藏0
  • setTimeout 或者 setInterval,關(guān)于 Javascript 計時器:需要知道

    摘要:所以,我們可以將理解為計時結(jié)束是執(zhí)行任務(wù)的必要條件,但是不是任務(wù)是否執(zhí)行的決定性因素。的意思是,必須超過毫秒后,才允許執(zhí)行。 先來回答一下下面這個問題:對于 setTimeout(function() { console.log(timeout) }, 1000) 這一行代碼,你從哪里可以找到 setTimeout 的源代碼(同樣的問題還會是你從哪里可以看到 setInterval 的...

    Warren 評論0 收藏0
  • 這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制

    摘要:事件完成,回調(diào)函數(shù)進(jìn)入。主線程從讀取回調(diào)函數(shù)并執(zhí)行。終于執(zhí)行完了,終于從進(jìn)入了主線程執(zhí)行。遇到,立即執(zhí)行。宏任務(wù)微任務(wù)第三輪事件循環(huán)宏任務(wù)執(zhí)行結(jié)束,執(zhí)行兩個微任務(wù)和。事件循環(huán)事件循環(huán)是實現(xiàn)異步的一種方法,也是的執(zhí)行機(jī)制。 本文的目的就是要保證你徹底弄懂javascript的執(zhí)行機(jī)制,如果讀完本文還不懂,可以揍我。不論你是javascript新手還是老鳥,不論是面試求職,還是日常開發(fā)工作...

    dreambei 評論0 收藏0
  • js 執(zhí)行機(jī)制 事件循環(huán)

    摘要:事件完成,回調(diào)函數(shù)進(jìn)入。我們來分析一段較復(fù)雜的代碼,看看你是否真的掌握了的執(zhí)行機(jī)制第一輪事件循環(huán)流程分析如下整體作為第一個宏任務(wù)進(jìn)入主線程,遇到,輸出。宏任務(wù)微任務(wù)第三輪事件循環(huán)宏任務(wù)執(zhí)行結(jié)束,執(zhí)行兩個微任務(wù)和。 關(guān)于JavaScript 首先js是單線程的,執(zhí)行任務(wù)肯定是一個接著一個。在最新的html5中提出了web-worker,但是JavaScript是單線程這一核心沒有改變,一...

    JackJiang 評論0 收藏0
  • JS忍者秘籍中定時器機(jī)制詳解

    摘要:設(shè)置和清除定時器直接引用忍者秘籍中的圖片注意定時器的時間間隔設(shè)為,也會有幾毫秒的延遲。以上參考資料忍者秘籍第章馴服線程和定時器 showImg(https://segmentfault.com/img/remote/1460000015353524?w=1024&h=681); 前言 前段時間剛看完《JS忍者秘籍》,雖說是15年出版的,有些東西是過時了,但像對原型鏈、閉包、正則、定時器...

    keelii 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<