国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript學習筆記整理_setTimeout的應用

2019-11-20 08:57:19
字體:
來源:轉載
供稿:網友

setTimeou的t應用

var ids = [];function foo1(i) {  this.i = i;  console.log('i = '+i);  ids[0] = setTimeout((function () {    foo1(i);  }),1000);}function foo2(j) {  this.j = j;  console.log('j = '+j);  ids[1] = setTimeout((function () {    foo2(j);  }),1000);}foo1(2);foo2(3);clearTimeout(ids[0]);clearTimeout(ids[1]);

當 setTimeout(f,n) 被調用時,它會返回一個 ID 標識并且計劃在將來大約n毫秒后調用f函數。 f函數只會被執行一次(遞歸執行的話就可以實現每n毫秒執行一次),基于 JavaScript 引擎的計時策略,以及本質上的單線程運行方式,所以其它代碼的運行可能會阻塞此線程。 因此沒法確保函數會在 setTimeout 指定的時刻被調用。通過在回調函數內部使用 setTimeout 函數來防止阻塞!

JavaScript 是異步的,setTimeout 只會執行回調函數一次,不過 setInterval會每隔 X 毫秒執行函數一次。 但是卻不鼓勵使用這個函數。當回調函數的執行被阻塞時,setInterval 仍然會發布更多的回調指令。在很小的定時間隔情況下,這會導致回調函數被堆積起來。

setTimeout 和 setInterval 也接受第一個參數為字符串的情況。 這個特性絕對不要使用,因為它在內部使用了隱藏的eval,由于 eval 在這種情況下不是被直接調用,因此傳遞到 setTimeout 的字符串會自全局作用域中執行,建議不要在調用定時器函數時,為了向回調函數傳遞參數而使用字符串的形式;當需要向回調函數傳遞參數時,可以創建一個匿名函數,在函數內執行真實的回調函數;

onscolll,onresize等是非常耗性能,那如果我們換成ajax請求的話,那么就會縮放一次窗口會連續觸發多次ajax請求,下面我們試著使用函數節流的操作試試一下;當然加個settimeout()的定時器就好了,

第一種封裝方法

var count = 0;function oCount() {  count++;  console.log(count);}window.onresize = function () {  delayFun(oCount)};function delayFun(method, thisArg) {  clearTimeout(method.props);  method.props = setTimeout(function () {    method.call(thisArg)  }, 200)}

第二種封裝方法

構造一個閉包,使用閉包的方式形成一個私有的作用域來存放定時器timer, timer是通過傳參數的形式引入的。

var count = 0;function oCount() {  count++;  console.log(count);}var funs= delayFun(oCount,100);window.onresize = function () {  funs()};function delayFun(func, wait) {  var timer = null;  return function () {    var context = this,      args = arguments;    clearTimeout(timer);    timer = setTimeout(function () {      func.apply(context, args);    }, wait)  };}

對第二種方法優化一下,性能會更好

這里返回一個函數,如果它被不間斷地調用,它將不會得到執行。該函數在停止調用 N 毫秒后,再次調用它才會得到執行。如果有傳遞 ‘immediate' 參數,會馬上將函數安排到執行隊列中,而不會延遲。

function delayFun (func, wait, immediate) {  var timeout;  return function() {    var context = this, args = arguments;    var later = function() {      timeout = null;      if (!immediate) func.apply(context, args);    };    var callNow = immediate && !timeout;    clearTimeout(timeout);    timeout = setTimeout(later, wait);    if (callNow) func.apply(context, args);  };};// 用法var myEfficientFn = delayFun (function() {  // 所有繁重的操作}, 250);window.addEventListener('resize', myEfficientFn);

函數不允許回調函數在指定時間內執行多于一次。當為一個會頻繁觸發的事件分配一個回調函數時,該函數顯得尤為重要。

setTimeout這么厲害,那么我們是可以在項目中大量使用嗎?

我個人是不建議的,在我們業務中,基本上是禁止在業務邏輯中使用setTimeout的,因為我所看到的很多使用方式都是一些問題不好解決,setTimeout作為一個hack的方式。

例如,當一個實例還沒有初始化的前,我們就使用這個實例,錯誤的解決辦法是使用實例時加個setTimeout,確保實例先初始化。

為什么錯誤?這里其實就是使用hack的手段

第一是埋下了坑,打亂模塊的生命周期

第二是出現問題時,setTimeout其實是很難調試的。

我認為正確的使用方式是,看看生命周期(可參考《關于軟件的生命周期 》),把實例化提到使用前執行

以上就是小編為大家帶來的JavaScript學習筆記整理_setTimeout的應用的全部內容了,希望對大家有所幫助,多多支持武林網~

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宁阳县| 梅河口市| 正蓝旗| 辽阳市| 九江县| 乌恰县| 大埔区| 蕉岭县| 日照市| 石柱| 玉山县| 车致| 大港区| 孝昌县| 白玉县| 湟源县| 萨嘎县| 遂溪县| 石棉县| 宁波市| 普洱| 英德市| 浦江县| 亚东县| 满城县| 云梦县| 柘城县| 嘉峪关市| 准格尔旗| 鸡西市| 上栗县| 乌审旗| 苍南县| 赞皇县| 开阳县| 永吉县| 苍梧县| 墨竹工卡县| 响水县| 汽车| 临沭县|