I'm calling an expensive function that dynamical changes as the end user types in a textbox. To reduce the amount of calls to the function I've used setTimeout to delay calling the function, and if the function is called again whilst waiting to run, it'll also remove the last function request via clearTimeout.The function for this is:// To not have different functions conflictfunction makeDelay() {    var timerID = false;    return function (fn, timeout) {        if (timerID !== false) {            clearTimeout(timerID);        }        if (timeout == undefined) {            timeout = 500;        }        timerID = setTimeout(function() {            timerID = false;            fn();        }, timeout);    }}var delay = makeDelay();var $peoplePicker = $('.ms-peoplePicker');var $results = $peoplePicker.find(.ms-PeoplePicker-results);However I don't know what the most idiomatic way to use this function is. I know that I can use one of the following:A closurefunction get(input, html_output) {    return function () {        if (!input) {            return;        }        $.ajax('/_api/pp_search/' + input).done(function (data) {            html_output[0].innerHTML = data;        })    }}$peoplePicker.on('input', '.ms-PeoplePicker-searchField', function(event) {    delay(get(event.currentTarget.value, $results));});bindfunction get(input, html_output) {    if (!input) {        return;    }    $.ajax('/_api/pp_search/' + input).done(function (data) {        html_output[0].innerHTML = data;    })}$peoplePicker.on('input', '.ms-PeoplePicker-searchField', function(event) {    delay(get.bind(undefined, event.currentTarget.value, $results));});Anonymous functionsfunction get(input, html_output) {    if (!input) {        return;    }    $.ajax('/_api/pp_search/' + input).done(function (data) {        html_output[0].innerHTML = data;    })}$peoplePicker.on('input', '.ms-PeoplePicker-searchField', function(event) {    delay(function () {        get(event.currentTarget.value, $results);    });});Using a closure seems like the nicest, as you don't have to explicitly make a delayed function at usage via bind or an anonymous function. However, anonymous functions seem to be the de facto way to call functions like these.Which, if any, way should I use this function?NotesI ask because I made a JavaScript program that heavily used closures for this style of function, but was really hard to read.
Closure, anonymous functions or binds on delayed functions
javascript;comparative review
Actually, what you are looking for is already done in Lodash via debounce or throttle. And yes, a closure is probably the best way to do this. So let's take your closure example and improve it.Instead of returning a function, why not just define the function normally. That way, there's no developer overhead. Devs shouldn't know about your limiter function just to make their APIs.// We'll be fine with thisfunction get(input, html_output) {  if (!input) return;      $.ajax('/_api/pp_search/' + input).done(function (data) {    html_output[0].innerHTML = data;  });}delay is a bit deceiving as the word delay can mean a lot of things. It can mean pause, which then equates to sleep which does an entirely different thing. debounce and throttle are actually better names. Verbose names aren't that bad as well (except for the extra keystrokes). Something like holdExecutionUntilAfter.Now for the implementation, let's accept a delay and the function we want to delay. Our return will be our proxy function that controls the real function from executing.function holdExecutionUntilAfter(fn, delay){  var timer = null;  return function(){    if(timer) clearTimeout(timer);    setTimeout(function(){      fn.apply(null, arguments);      clearTimeout(timer);    }, delay);  }}As simple as that! What it does is get a reference of the real function into a closure. Then we return a proxy function which well be using to call the real function. When it gets called, it resets the timer and kicks off another. We use apply to pass in the arguments like you normally would in the regular call. Usage will be as simple as:var get = delay(function(input, html_output){  if (!input) return;      $.ajax('/_api/pp_search/' + input).done(function (data) {    html_output[0].innerHTML = data;  });}, 500);get(event.currentTarget.value, $results);// or verboselyfunction get(input, html_output){  if (!input) return;      $.ajax('/_api/pp_search/' + input).done(function (data) {    html_output[0].innerHTML = data;  });}var proxiedGet = delay(get, 500);proxiedGet(event.currentTarget.value, $results);