简体   繁体   中英

wanting pattern for best way to pass function parameters into setTimeout call in JavaScript

I'm struggling with the best way to pass all the parameters passed into a function through to the function in setTimeout . That is, in my example below, I pass one parameter, but it seems to me as this gets more complex it gets ugly (multiple parameters). I'm hoping for a clean pattern to do this since I do it a lot.

onSessionTimeComboChange: function (combo, newValue, oldValue, eOpts) {
    var me = this;
    me.newValue = newValue;
    setTimeout(function () {
        var x = me.newValue;
        debugger;
    }, 100);
}

The reason you don't have access to the main function variables in the callback is that the code executed by setTimeout() is run in a separate execution context to the function from which it was called. In simpler terms, this is not the same in the callback.

If you don't want to use Javascript libraries that provide functions to bind a callback to a context (see jQuery.proxy and underscore.bind ), you would have to write your own non-native setTimeout function to fix this.

Here is the solution proposed in the web api docs (See section The "this" problem ):

window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
  var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
  return __nativeST__(vCallback instanceof Function ? function () {
    vCallback.apply(oThis, aArgs);
  } : vCallback, nDelay);
};

If you don't want to go that far, an improvement to your code would be to pass the arguments to the callback as parameters of setTimeout :

var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);

Check the JavaScript web api for more details.

So in your example, you could just write something like:

setTimeout(function (x) {
    debugger;
}, 100, newValue);

Javascript supports closures so you can indeed pass any parameters you need to any callback without much effort:

function bar(x, y, z) {
    console.log([x, y, z]);
}

for (var i=0; i<5; i++) {
    (function(x, y, z){
        setTimeout(function(){bar(x, y, z);}, i*1000+1000);
     })(i, i*2, i*3);
}

The only tricky part is that you cannot just say

setTimeout(function(){bar(i, i*2, i*3)}, i*1000+1000);

because the closure captures the variables (not the current values), so all the registered functions would actually use the same i value in this case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM