suchen

Heim  >  Fragen und Antworten  >  Hauptteil

javascript - Was die Funktionsdrosselung betrifft, fühlt sich fn.appplay() im Timer seltsam an?

Der Code ist nicht kompliziert, die Logik ist sehr einfach, es handelt sich um eine Funktionsdrosselung, ich habe den Code direkt eingegeben.

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)
    }
  }
}

Theoretisch ist es eine große Zahl, wenn ich die Größe des Browserfensters ständig ändere (das heißt, das Intervall muss weniger als 1 Sekunde betragen). doSomthing 从第二次开始是不会被执行的。因为我在不断的执行 cleraTimeout,实际运行结果是 console.log('第'+count+'次执行) 确实没有被打印出来,但是当我停止改变浏览器窗口的时候,发现打印出来的 count 并不是 1

Das zeigt das in diesem Code:

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

Aber es wurde ausgeführt, bitte sagen Sie mir das Prinzip? Oder stimmt etwas mit meinem Code selbst nicht? setTimeout() 里的匿名函数没有被执行,但是匿名函数里的 fn.apply()

女神的闺蜜爱上我女神的闺蜜爱上我2748 Tage vor731

Antworte allen(2)Ich werde antworten

  • 代言

    代言2017-06-14 10:54:57

    除了setTimeout里的之外,在

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

    在改变浏览器大小时,else里的这个fn.apply会每隔threshhold毫秒执行一次

    所以setTimeout确实只执行了一次,其余的次数是else里的fn.apply执行的

    Antwort
    0
  • 某草草

    某草草2017-06-14 10:54:57

    一次改变尺寸的操作会触发多次onresize,第一次会触发else的内容,其他的触发if里面的内容,由于你clearTimeout()写在setTimeout前面,那最后一次setTimeout的内容会被执行,所以一次改变尺寸会触发两次doSomthing,而打印出来的count至少会相差2,你要是每次改变尺寸的操作事件大于250ms小于1s,那count的值会更大。

    Antwort
    0
  • StornierenAntwort