javascript - Mengenai pendikitan fungsi, fn.appplay() dalam pemasa terasa pelik?
女神的闺蜜爱上我
女神的闺蜜爱上我 2017-06-14 10:52:57
0
2
702

Kodnya tidak rumit, logiknya sangat mudah, ia adalah pendikitan fungsi, saya meletakkan kod terus.

var count = 0

setInterval(() => console.log(new Date().getSeconds()),1000)

function doSomthing() {
  console.log('懵逼。。。。')
  count ++;
}

window.onresize = throttle(doSomthing,1000)

function throttle(fn, threshhold) {
  // 记录上次执行的时间
  var last

  // 定时器
  var timer

  // 默认间隔为 250ms
  threshhold || (threshhold = 250)

  // 返回的函数,每过 threshhold 毫秒就执行一次 fn 函数
  return function () {

    // 保存函数调用时的上下文和参数,传递给 fn
    var context = this
    var args = arguments

    var now = +new Date()

    // 如果距离上次执行 fn 函数的时间小于 threshhold,那么就放弃
    // 执行 fn,并重新计时
    if (last && now < last + threshhold) {
      clearTimeout(timer)

      // 保证在当前时间区间结束后,再执行一次 fn
      timer = setTimeout(function () {
        last = now
        console.log('第'+count+'次执行')
        fn.apply(context, args)
      }, threshhold)

      // 在时间区间的最开始和到达指定间隔的时候执行一次 fn
    } else {
      last = now
      fn.apply(context, args)
    }
  }
}

Secara teorinya, apabila saya terus menukar saiz tetingkap penyemak imbas (iaitu, selang mesti kurang daripada 1s), doSomthing 从第二次开始是不会被执行的。因为我在不断的执行 cleraTimeout,实际运行结果是 console.log('第'+count+'次执行) 确实没有被打印出来,但是当我停止改变浏览器窗口的时候,发现打印出来的 count 并不是 1, dan ia adalah jumlah yang besar.

Ini menunjukkan bahawa dalam kod ini:

timer = setTimeout(function () {
        last = now
        console.log('第'+count+'次执行')
        fn.apply(context, args)
      }, threshhold)`

setTimeout() 里的匿名函数没有被执行,但是匿名函数里的 fn.apply() Tetapi ia telah dilaksanakan, sila beritahu saya prinsipnya? Atau adakah terdapat sesuatu yang salah dengan kod saya sendiri?

女神的闺蜜爱上我
女神的闺蜜爱上我

membalas semua(2)
代言

Selain mereka dalam setTimeout, dalam

if (last && now < last + threshhold) { \*...*\ }
else {
     last = now
     fn.apply(context, args) //这里还有一个fn.apply()
}

Apabila menukar saiz penyemak imbas, fn.apply in else ini akan dilaksanakan setiap milisaat ambang

Jadi setTimeout确实只执行了一次,其余的次数是else里的fn.apply memang hanya dilaksanakan sekali, selebihnya masa dilaksanakan oleh

dalam lain 🎜
某草草

Operasi tukar saiz akan mencetuskan berbilang onresize Kali pertama akan mencetuskan kandungan else, dan yang lain akan mencetuskan kandungan dalam if Memandangkan anda menulis clearTimeout() sebelum setTimeout, kandungan setTimeout terakhir akan dilaksanakan . , jadi menukar saiz sekali akan mencetuskan doSomthing dua kali, dan kiraan yang dicetak akan berbeza sekurang-kurangnya 2. Jika peristiwa operasi setiap perubahan saiz lebih besar daripada 250ms dan kurang daripada 1s, nilai kiraan akan lebih besar.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan