-1

I'm trying to debounce the user input into two boxes and then call an expensive function. Here is a minimum example, that doesn't work:

$('#slider_min').on('keyup', LetItRoll )
$('#slider_max').on('keyup', LetItRoll )

async function LetItRoll(){
   const amin = debounceProimse(UpdateSliderMin,300)
   const amax = debouncePromise(UpdateSliderMax,300)
   const result = await Promise.all([amin,amax])
   
   const result_value = [amin,amax]
   alert(result)
   return result
}

function UpdateSliderMin(){ 
    const slider_min = document.getElementById('slider_min').value       
    return slider_min        // not a promise, but doesnt work if I create a promise
}

function UpdateSliderMax(){
    const slider_max = document.getElementById('slider_max').value   
    return slider_max        
}

For debouncePromise I have tried the suggestions both in Debounce function implemented with promises https://www.30secondsofcode.org/js/s/debounce-promise

Actually, I dont really care if the debounce returns a promise because I think "on" never returns anything, so cannot create a chain? Either way, I have restructured the same with other debounce code on the internet, including lodash debounce. They all give the same thing: if you type fast enough then you create multiple calls to "alert"

I also read in https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/ that callbacks may have higher priority over microtasks, so conceivably that is what is happening?

I was also wondering if each click was creating a separate version of debounce, so I tried taking the chain of Promises to be a global variable so each new debounce would add to the old promise. That didnt work either.

Seems this should be easy, but I am completely stumped....

Tunneller
  • 381
  • 2
  • 13
  • Making event handlers `async` for jQuery is pointless; the library doesn't care. – Pointy Feb 25 '23 at 19:19
  • Hm. You may be correct, but I thought I could not do an "await" outside an async function? – Tunneller Feb 25 '23 at 19:34
  • Maybe I need a .when ?? https://lostechies.com/derickbailey/2012/03/27/providing-synchronous-asynchronous-flexibility-with-jquery-when/#:~:text=You%20can%20use%20jQuery%20to,whether%20or%20not%20it's%20async. – Tunneller Feb 25 '23 at 19:38
  • 1
    Well that's certainly true, but understand that jQuery is not going to do anything special with your function. But yea if you need the `await` then you need the `async`. – Pointy Feb 25 '23 at 19:39
  • 1
    What is your end goal here? Forget your `debounce()` implementations and promises and task queues for a second. What EXACT behavior do you want when the user types in the slider_min and slider_max fields? And, please be specific about what want. For example, how long do you want it to wait for no more typing before doing something? – jfriend00 Feb 25 '23 at 19:46
  • Changes in one of two input boxes should trigger a call to replot, which will be an expensive operation. I figure around 450ms is a good value to wait, definitely not trigger on each keyup event. Most users having clicked on one box will immediately go over to the other box, eg if they have just finished typing into the box on the left and then now start typing into the right box then that should could as the same event. – Tunneller Feb 25 '23 at 21:51

1 Answers1

1

Here's a manually created wrapper that only processes your key press results after a delay of 750ms with no further typing in either of the two fields. You can run the snippet and try it. It will sum the two values and display the result, whenever you pause for more than 750ms and neither field is empty.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Min: <input type="text" id="slider_min"><br>
Max: <input type="text" id="slider_max"><br>
Result: <span id="slider_result"></span>

<script>

// wrapper function (returns a new function)
function delay(fn, delayT) {
    let timer;
    return function() {
        // clear prior timer
        if (timer) {
            clearTimeout(timer);
        }
        // process results in delayT
        timer = setTimeout(() => {
            // delayT must have passed with no more calls
            // so call the function now
            timer = null;
            fn();
        }, delayT);
    }
}

function letItRoll() {
    // process the result here
    const minT = document.getElementById('slider_min').value;
    const maxT = document.getElementById('slider_max').value;
    if (minT !== "" && maxT !== "") {
        document.getElementById('slider_result').innerHTML = parseInt(minT, 10) + parseInt(maxT, 10);
    }
}

const runIt = delay(letItRoll, 750);

$('#slider_min').on('keyup', runIt);
$('#slider_max').on('keyup', runIt);

</script>
jfriend00
  • 683,504
  • 96
  • 985
  • 979