最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

頁面中實(shí)現(xiàn)setInterval和setTimeout效果示例詳解

 更新時(shí)間:2022年09月15日 15:20:50   作者:來世做春風(fēng)  
這篇文章主要為大家介紹了不使用setTimeout和setInterval在頁面中實(shí)現(xiàn)setInterval和setTimeout效果示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

昨天面試一家公司,面試官問我,如何在不使用setTimeout和setInterval在頁面中實(shí)現(xiàn)setInterval和setTimeout效果,我:????。

后來我仔細(xì)想了一下,思路就是獲取時(shí)間戳,然后用遞歸判斷實(shí)現(xiàn)。那么思路是這樣,下面就代碼實(shí)現(xiàn)一下吧。

setTimeout的實(shí)現(xiàn)

function setTimeout_(dalay) {
  // 第一次的時(shí)間戳
  const timestampFirst = Date.now()
  // 返回一個(gè)promise對(duì)象
  return new Promise(reslove => {
    // 操作
    function handle() {
      // 每一次的時(shí)間戳
      const timestamp = Date.now()
      // 當(dāng)時(shí)間戳減去后大于延遲時(shí)間
      if ((timestamp - timestampFirst) >= dalay) {
        // 成功回調(diào)
        reslove()
      } else {
        // 遞歸
        handle()
      }
    }
    // 初次調(diào)用
    handle()
  })
}
setTimeout_(10).then(() => {
  alert(10)
})

上面的代碼看似沒有毛病,但是運(yùn)行后發(fā)現(xiàn),setTimeout_()里面的值設(shè)置小一點(diǎn)沒有問題(比如2、3),但是一旦超過,就會(huì)造成堆棧溢出,乃至報(bào)錯(cuò)。

解決堆棧溢出方法

下面隆重介紹一個(gè)人,蹦床函數(shù)(trampoline)

蹦床函數(shù)(trampoline)就是將 遞歸執(zhí)行 轉(zhuǎn)為 循環(huán)執(zhí)行
執(zhí)行的都是同樣的步驟,只是反復(fù)執(zhí)行,就好像在蹦床,跳上去,掉下來,在跳上去…

  • 蹦床函數(shù)的實(shí)現(xiàn):
function trampoline(f){
  while(f && f instanceof Function && falg){
   f = f()
  }
  return f
}

它接受一個(gè)函數(shù)f作為參數(shù)。只要f執(zhí)行后返回一個(gè)函數(shù),就繼續(xù)執(zhí)行。注意,這里是返回一個(gè)函數(shù),然后執(zhí)行該函數(shù),而不是函數(shù)里面調(diào)用函數(shù),這樣就避免了遞歸執(zhí)行,從而就消除了調(diào)用棧過大的問題

最終實(shí)現(xiàn)

// 定時(shí)器
function setTimeout_(dalay) {
  // 第一次的時(shí)間戳
  const timestampFirst = Date.now()
  // 返回一個(gè) Promise 對(duì)象
  return new Promise(reslove => {
    // 具體操作
    function handle() {
      // 每一次的時(shí)間戳
      const timestamp = Date.now()
      // 當(dāng)時(shí)間戳減去后大于延遲時(shí)間
      if ((timestamp - timestampFirst) >= dalay) {
       // 成功回調(diào)
        reslove()
      } else {
       // 不滿足條件繼續(xù)調(diào)用
        return handle
      }
    }
    // 調(diào)用蹦床函數(shù)、將遞歸變?yōu)檠h(huán)
    trampoline(handle)()
  })
}
// 蹦床函數(shù)
function trampoline(f){
  while(f && f instanceof Function){
    f = f()
  }
  return f
}
setTimeout_(1000).then(res => {
  alert(1000)
})

以上的代碼,就能實(shí)現(xiàn)效果了

思路:定義一個(gè)函數(shù),參數(shù)為延遲時(shí)間,調(diào)用時(shí)記錄一個(gè)第一次時(shí)間戳,然后里面返回一個(gè)Promise對(duì)象,再里面有一個(gè)閉包,是執(zhí)行遞歸操作的函數(shù),這個(gè)函數(shù)里面做的事就是記錄每一次的時(shí)間戳,然后減去第一次的時(shí)間戳,得出的就是間隔時(shí)間,跟規(guī)定的間隔時(shí)間作比較,如果大于的話,就調(diào)用Promise成功回調(diào)。再下面就是將遞歸轉(zhuǎn)為循環(huán),防止堆棧溢出。最后調(diào)用

setInterval的實(shí)現(xiàn)

這個(gè)跟setTimeout差不多,區(qū)別就是這個(gè)需要每隔一段時(shí)間執(zhí)行代碼,并且需要手動(dòng)清除

// 如果 falg 為 false就不會(huì)繼續(xù)執(zhí)行循環(huán)操作
let falg = true
// 蹦床函數(shù)技術(shù),利用循環(huán)
function trampoline(f){
  while(f && f instanceof Function && falg){
    f = f()
  }
  return f
}
// 計(jì)時(shí)器
function setInterval_(f, dalay) {
  // 第一次的時(shí)間戳
  let timestampFirst = Date.now()
  // 操作
  function handle() {
    // 每一次的時(shí)間戳
    const timestamp = Date.now()
    if ((timestamp - timestampFirst) >= dalay) {
      // 間隔時(shí)間到了就重置第一次時(shí)間戳
      timestampFirst = Date.now()
      // 調(diào)用函數(shù)
      f()
    }
    return handle
  }
  trampoline(handle)()
}
let count = 0
// 調(diào)用
setInterval_(function() {
  count ++
  if (count === 3) {
    falg = false
  }
  console.log(count)
}, 1000)

上面這個(gè)代碼我定義的是在控制臺(tái)輸入1、2、3,然后關(guān)閉

思路:同樣是判斷時(shí)間戳,但是跟setTimeout不一樣的是每次執(zhí)行里面的函數(shù)需要重置時(shí)間,達(dá)到每次執(zhí)行的效果。并且在蹦床函數(shù)里面的while增加一個(gè)判斷,用來控制計(jì)時(shí)器的停止。

總結(jié):這種東西了解一下,以后當(dāng)個(gè)吹牛逼資本就可以了,畢竟這性能嘛.....

以上就是頁面中實(shí)現(xiàn)setInterval和setTimeout效果示例詳解的詳細(xì)內(nèi)容,更多關(guān)于setInterval setTimeout頁面效果的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JavaScript 組件之旅(二)編碼實(shí)現(xiàn)和算法

    JavaScript 組件之旅(二)編碼實(shí)現(xiàn)和算法

    話說上期我們討論了隊(duì)列管理組件的設(shè)計(jì),并且給它取了個(gè)響亮而獨(dú)特的名字:Smart Queue. 這次,我們要將之前的設(shè)計(jì)成果付諸實(shí)踐,用代碼來實(shí)現(xiàn)它。
    2009-10-10
  • javascript判斷圖片是否加載完成的方法推薦

    javascript判斷圖片是否加載完成的方法推薦

    下面小編就為大家?guī)硪黄猨avascript判斷圖片是否加載完成的方法推薦。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。
    2016-05-05
  • 微信公眾平臺(tái) 發(fā)送模板消息(Java接口開發(fā))

    微信公眾平臺(tái) 發(fā)送模板消息(Java接口開發(fā))

    這篇文章主要介紹了微信公眾平臺(tái) 發(fā)送模板消息(Java接口開發(fā)),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • js中arguments的用法(實(shí)例講解)

    js中arguments的用法(實(shí)例講解)

    這篇文章主要是對(duì)js中arguments的用法進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助
    2013-11-11
  • 微信小程序中實(shí)現(xiàn)雙向綁定的實(shí)戰(zhàn)過程

    微信小程序中實(shí)現(xiàn)雙向綁定的實(shí)戰(zhàn)過程

    最近在小程序的開發(fā)過程中,需要用到雙向綁定,遇到報(bào)錯(cuò)才知道微信本身是不支持對(duì)象雙向綁定的,折騰一番找到解決方案,下面這篇文章主要給大家介紹了關(guān)于微信小程序中實(shí)現(xiàn)雙向綁定的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • Javascript中的call()方法介紹

    Javascript中的call()方法介紹

    這篇文章主要介紹了Javascript中的call()方法介紹,本文講解了Call() 語法、Call() 參數(shù)、Javascript中的call()方法、Call()方法的實(shí)例等內(nèi)容,需要的朋友可以參考下
    2015-03-03
  • 讓瀏覽器非阻塞加載javascript的幾種方法小結(jié)

    讓瀏覽器非阻塞加載javascript的幾種方法小結(jié)

    通常大多數(shù)瀏覽器是并行下載資源的,但由于外部腳本的特殊性例如通過腳本改變文檔的DOM結(jié)構(gòu)、腳本之間的存在依賴關(guān)系、使用document.write 向頁面輸出HTML等。
    2011-04-04
  • tween.js緩動(dòng)補(bǔ)間動(dòng)畫算法示例

    tween.js緩動(dòng)補(bǔ)間動(dòng)畫算法示例

    本篇文章主要介紹了tween.js緩動(dòng)補(bǔ)間動(dòng)畫示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-02-02
  • JavaScript中常見的數(shù)據(jù)類型判斷方法小結(jié)

    JavaScript中常見的數(shù)據(jù)類型判斷方法小結(jié)

    在?JS?編程中,正確判斷數(shù)據(jù)類型是必備技能,也是面試常問的內(nèi),本文將探討四種常用的數(shù)據(jù)類型判斷方法,通過了解它們的特點(diǎn)和適用范圍,能夠更好地處理不同數(shù)據(jù)類型的情況,避免出現(xiàn)錯(cuò)誤和提升代碼質(zhì)量,需要的朋友可以參考下
    2023-06-06
  • JavaScript頭像上傳插件源碼分享

    JavaScript頭像上傳插件源碼分享

    這篇文章主要為大家分享介紹了JavaScript頭像上傳插件源碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-03-03

最新評(píng)論

洮南市| 东山县| 五原县| 中宁县| 喀喇沁旗| 仁布县| 莎车县| 寿光市| 崇仁县| 辉县市| 余庆县| 沙洋县| 泸西县| 神农架林区| 宁南县| 措美县| 沂水县| 广水市| 郁南县| 怀来县| 雷州市| 历史| 石柱| 鄢陵县| 台中市| 盐城市| 百色市| 山丹县| 乌苏市| 泸州市| 昭通市| 社会| 罗源县| 六盘水市| 土默特右旗| 龙海市| 滨州市| 景谷| 五常市| 淳安县| 平湖市|