3 different type of throttle function in JavaScript | JavaScript Interview Question - 53

แชร์
ฝัง
  • เผยแพร่เมื่อ 2 ธ.ค. 2024

ความคิดเห็น • 19

  • @loneWolff1995
    @loneWolff1995 5 หลายเดือนก่อน +1

    *Last one is way Complex* !

  • @yynnooot
    @yynnooot 5 หลายเดือนก่อน +1

    Within the else block, when there is a `lastRan`, why do you need to check if (Date.now() - lastRan >= delay) before calling the fn? Isn't that repetitive because we are already setting the delay with the new timeout (lastTimerid) with: delay - (Date.now() - lastRan)?

  • @nikhilvadrevu7351
    @nikhilvadrevu7351 ปีที่แล้ว +1

    Hey Prashanth, I understand the function's context depends on from where it is being "called" rather than where it is "declared" and this might sound trivial but can you explain with an example why would we require ( or how critical it is to declare ) the line "const context = this" inside the inner function of throttle function with an example and what "this" inside it would point to and what happens if we don't have this line ? and if we were use arrow functions in all places do we still require the line "const context = this" ? .

    • @Learnersbucket
      @Learnersbucket  ปีที่แล้ว

      Read this article to understand function and this learnersbucket.com/tutorials/es6/function-this-in-javascript/

    • @nikhilvadrevu7351
      @nikhilvadrevu7351 ปีที่แล้ว +1

      ​@@Learnersbucket After going through your blog I learnt that
      1. the "this" inside a function call is window / global in non-strict and undefined in strict mode
      2. the "this" inside an inner function is window ( non-strict ) / undefined ( strict mode)
      3. the "this" inside a method ( a function declared inside an object ) is the object itself
      4. the "this" inside a inner function of a method is window / undefined
      5. the "this" inside a function extracted/separated from an object is window/undefined
      6. the "this" inside an arrow function is always its parent context
      7. the "this" inside an arrow function when declared at the top is window/ global
      8. the "this" context can be changed by using .bind, .call, .apply
      9. the bound function's context cannot be changed by rebounding / call / apply but can be changed by new ( function constructor invocation )
      10. arrow's function this is static and cannot be changed even by bind/call/appy and throws Typeerror ( TypeError: is not a constructor ) when invoked with "new" keyword
      Finally the function's context depends on various factors like, whether we are calling function:
      1. directly / as a method
      2. by bind/apply/call
      3. with new key word ( Function constructor ) invocation
      4. is an arrow function
      the line "const context = this" inside the inner function of throttle implemenation makes sense when we attach the throttle as an event handler and we want to execute event handler in the context of "input" so that the "this" inside the inner function of throttle would point to "input" elment's context rather than window/global or even undefined in strict case.

  • @pitanihamsaraj735
    @pitanihamsaraj735 ปีที่แล้ว +1

    Correct me if any mistake, this version of mine looks simpler to understand to mwe
    function throttle(fn, delay) {
    let lastRun = 0;
    let timerId = null;
    return (...args) => {
    const now = Date.now();
    if (now - lastRun >= delay) {
    fn.apply(this, args);
    lastRun = now;
    } else {
    clearTimeout(timerId);
    timerId = setTimeout(() => {
    fn.apply(this, args);
    lastRun = now;
    }, delay);
    }
    };
    }

    • @kumaramresh7905
      @kumaramresh7905 8 หลายเดือนก่อน

      this will become debouncing i guess

  • @makesh-kumar
    @makesh-kumar ปีที่แล้ว +1

    Hi Prashanth, Do you see any problem with below approach,
    const throttleWithLeadingTime = (fn, delayInMs) => {
    let timer = null;
    return function (...args) {
    if (timer === null) { // when invoked for first time
    fn.call(this, ...args);
    timer = Date.now() + delayInMs;
    } else if (Date.now() > timer) {
    fn.call(this, ...args);
    timer = Date.now() + delayInMs;
    }
    };
    };
    const throttleWithTrailingTime = (fn, delayInMs) => {
    let timer = null;
    return function (...args) {
    if (timer === null) { // when invoked for first time
    timer = Date.now() + delayInMs;
    } else if (Date.now() > timer) {
    fn.call(this, ...args);
    timer = Date.now() + delayInMs;
    }
    };
    };

    • @Learnersbucket
      @Learnersbucket  ปีที่แล้ว +1

      How do you cancel previous invoked function, if that happens before the delay?

    • @makesh-kumar
      @makesh-kumar ปีที่แล้ว +1

      If it is invoked before the delay, it will not go inside IF/ELSE condition, so nothing will happen
      Pls correct me, if I'm wrong😊

  • @Ashishume
    @Ashishume ปีที่แล้ว +1

    i created the below method seems to work fine for me, can u spot any loop holes in the below implementation?
    const throttler = (arr, limit, callback, delay) => {
    let flag = true;
    let queue = [...arr];
    return function () {
    if (flag) {
    const tasks = queue.splice(0, limit);
    callback(tasks);
    flag = false;
    setTimeout(() => {
    flag = true;
    }, delay);
    }
    };
    };
    const newBtn = document.getElementById("btn");
    newBtn.addEventListener(
    "click",
    throttler(
    [1, 2, 3, 4, 5, 6, 7, 8],
    2,
    (tasks) => {
    console.log(tasks);
    },
    2000
    )
    );

    • @Ashishume
      @Ashishume ปีที่แล้ว

      can u comment something?

  • @sachinsingh-jb7td
    @sachinsingh-jb7td ปีที่แล้ว +1

    function throttle(cb, delay = 250) {
    let shouldWait = false
    return (...args) => {
    if (shouldWait) return
    cb(...args)
    shouldWait = true
    setTimeout(() => {
    shouldWait = false
    }, delay)
    }
    }
    Will this work as throttle by time function ?

    • @Learnersbucket
      @Learnersbucket  ปีที่แล้ว

      Nope

    • @whd793
      @whd793 ปีที่แล้ว +1

      How come?@@Learnersbucket

    • @Learnersbucket
      @Learnersbucket  ปีที่แล้ว

      @@whd793 try to run this, there will be mismatch in running consecutive throttles

    • @AnudeepKing
      @AnudeepKing ปีที่แล้ว +2

      Imagine you clicked twice, function will be executed only once. But in case of Prashant's implementation , function will be executed twice with the delay specified. I think there's a mis-match in how we understand throttling :)

  • @harshitsrivastava2583
    @harshitsrivastava2583 ปีที่แล้ว +1

    Is this correct ?
    For Leading ->
    const leadingThrottle = function (fn , delay) {
    let prevR ;
    let timer ;
    return function(...args){
    if(!prevR){
    fn.apply(this , args);
    timer = Date.now();
    prevR = true;
    }
    else{
    if(Date.now() - timer >= delay){
    fn.apply(this,args);
    timer = Date.now();
    }
    }
    }
    }
    For Trailing ->
    const trailingThrottle = function(fn, delay) {
    let lastTimerid;
    let lastRan = Date.now();
    return function (...args) {
    const context = this;
    clearTimeout (lastTimerid);
    lastTimerid = setTimeout(() => {
    if (Date.now() - lastRan >= delay) {
    fn.apply (context, args);
    lastRan = Date.now() ;
    }
    }, delay - (Date.now() - lastRan));
    }
    }