如何通过一个回调函数传递变量数量的参数?

时间:2022-12-04 08:02:06

I'm using a function to lazy-load the Sizzle selector engine (used by jQuery):

我正在使用一个函数来延迟加载Sizzle选择引擎(jQuery使用):

var sizzle_loaded;

// load the Sizzle script
function load_sizzle(module_name) {

  var script;

  // load Sizzle script and set up 'onload' and 'onreadystatechange' event
  // handlers to ensure that external script is loaded before dependent
  // code is executed
  script = document.createElement('script');
  script.src = 'sizzle.min.js';
  script.onload = function() {
    sizzle_loaded = true;
    gather_content(module_name);
  };
  script.onreadystatechange = function() {
    if ((script.readyState === 'loaded' || script.readyState === 'complete') &&
        !sizzle_loaded) {
      sizzle_loaded = true;
      gather_content(module_name);
    }
  };

  // append script to the document
  document.getElementsByTagName('head')[0].appendChild(script);

}

I set the onload and onreadystatechange event handlers, as well as the sizzle_loaded flag to call another function (gather_content()) as soon as Sizzle has loaded. All of this is needed to do this in a cross-browser way.

我设置onload和onreadystatechange事件处理程序,以及sizzle_loaded标志,在Sizzle加载完毕后立即调用另一个函数(收集内容())。所有这些都需要以跨浏览器的方式进行。

Until now, my project only had to lazy-load Sizzle at one point in the script, so I was able to just hard-code the gather_content() function call into the load_sizzle() function.

到目前为止,我的项目只需要在脚本中的一个点上延迟加载Sizzle,所以我能够将收集的函数调用硬编码到load_sizzle()函数中。

However, I now need to lazy-load Sizzle at two different points in the script, and call a different function either time once it's loaded. My first instinct was to modify the function to accept a callback function:

但是,我现在需要在脚本中的两个不同的点上延迟加载Sizzle,并在加载时调用一个不同的函数。我的第一反应是修改函数来接受回调函数:

var sizzle_loaded;

// load the Sizzle script
function load_sizzle(module_name, callback) {

  var script;

  // load Sizzle script and set up 'onload' and 'onreadystatechange' event
  // handlers to ensure that external script is loaded before dependent
  // code is executed
  script = document.createElement('script');
  script.src = 'sizzle.min.js';
  script.onload = function() {
    sizzle_loaded = true;
    callback(module_name);
  };
  script.onreadystatechange = function() {
    if ((script.readyState === 'loaded' || script.readyState === 'complete') &&
        !sizzle_loaded) {
      sizzle_loaded = true;
      callback(module_name);
    }
  };

  // append script to the document
  document.getElementsByTagName('head')[0].appendChild(script);

}

Then, I could just call it like this:

然后,我可以这样叫它:

load_sizzle(module_name, gather_content);

However, the other callback function that I need to use takes more parameters than gather_content() does.

但是,我需要使用的另一个回调函数需要的参数比收集内容()要多。

How can I modify my function so that I can specify a variable number of parameters, to be passed with the callback function? Or, am I going about this the wrong way?

如何修改我的函数,以便我可以指定一个参数的可变数目,以传递回调函数?或者,我是不是走错了路?

Ultimately, I just want to load Sizzle, then call any function that I need to (with any arguments that it needs) once it's done loading.

最后,我只是想加载Sizzle,然后调用任何我需要的函数(在它需要的参数中)。

Thanks for any help!

感谢任何帮助!

3 个解决方案

#1


3  

The general idea here is to create a closure or lambda. In a way, you can consider them as a function that's pre-loaded with parameters that's ready to be called. This is also sometimes called a delegate.

这里的大意是创建一个闭包或lambda。在某种程度上,您可以把它们看作是一个预先装载了可以调用的参数的函数。这有时也称为委托。

load_sizzle( module_name, function()
{
  gather_content();
});

Then, for your other case

然后,为你的另一个案子。

load_sizzle( module_name, function()
{
  some_other_function( param1, param2 );
});

More reading on closures.

更多的阅读闭包。

#2


2  

You can use arguments array to get all arguments that were passed into the function.

您可以使用参数数组来获取传入函数的所有参数。

function example() {
for( var i = 0; i < arguments.length; i++ ) {
    alert('argument ' + i + ' ' + arguments[i]);
}
}

example('any', 'number', 'of', 'arguments);

#3


2  

You can use the apply method on the callback:

您可以在回调中使用apply方法:

function load_sizzle(module_name, callback,args) {

  var script, args=args || []; //Be sure that an array is passed

  // load Sizzle script and set up 'onload' and 'onreadystatechange' event
  // handlers to ensure that external script is loaded before dependent
  // code is executed
  script = document.createElement('script');
  script.src = 'sizzle.min.js';
  script.onload = function() {
    sizzle_loaded = true;
    callback.apply(window,[module_name].concat(args)); //Add the module_name as first argument and then every other argument specified by the user
  };
  script.onreadystatechange = function() {
    if ((script.readyState === 'loaded' || script.readyState === 'complete') &&
        !sizzle_loaded) {
      sizzle_loaded = true;
      callback(module_name);
    }
  };

  // append script to the document
  document.getElementsByTagName('head')[0].appendChild(script);

}

Then as third argument of load_sizzle you can pass an array of extra arguments for the function.

然后作为load_sizzle的第三个参数,您可以传递函数的额外参数数组。

You can also improve the code with this:

您还可以通过以下方式改进代码:

function load_sizzle(module_name, callback,args,bind) {

  var script, args=args || [],bind=bind || window;

  // load Sizzle script and set up 'onload' and 'onreadystatechange' event
  // handlers to ensure that external script is loaded before dependent
  // code is executed
  script = document.createElement('script');
  script.src = 'sizzle.min.js';
  script.onload = function() {
    sizzle_loaded = true;
    callback.apply(bind,[module_name].concat(args)); //Add the module_name as first argument and then every other argument specified by the user
  };
  script.onreadystatechange = function() {
    if ((script.readyState === 'loaded' || script.readyState === 'complete') &&
        !sizzle_loaded) {
      sizzle_loaded = true;
      callback(module_name);
    }
  };

  // append script to the document
  document.getElementsByTagName('head')[0].appendChild(script);

}

In this way the argument number 4 (if specified) can be an object that will be the "this" inside the callback that you pass.

这样,参数4(如果指定的话)可以是您通过的回调中的“this”对象。

#1


3  

The general idea here is to create a closure or lambda. In a way, you can consider them as a function that's pre-loaded with parameters that's ready to be called. This is also sometimes called a delegate.

这里的大意是创建一个闭包或lambda。在某种程度上,您可以把它们看作是一个预先装载了可以调用的参数的函数。这有时也称为委托。

load_sizzle( module_name, function()
{
  gather_content();
});

Then, for your other case

然后,为你的另一个案子。

load_sizzle( module_name, function()
{
  some_other_function( param1, param2 );
});

More reading on closures.

更多的阅读闭包。

#2


2  

You can use arguments array to get all arguments that were passed into the function.

您可以使用参数数组来获取传入函数的所有参数。

function example() {
for( var i = 0; i < arguments.length; i++ ) {
    alert('argument ' + i + ' ' + arguments[i]);
}
}

example('any', 'number', 'of', 'arguments);

#3


2  

You can use the apply method on the callback:

您可以在回调中使用apply方法:

function load_sizzle(module_name, callback,args) {

  var script, args=args || []; //Be sure that an array is passed

  // load Sizzle script and set up 'onload' and 'onreadystatechange' event
  // handlers to ensure that external script is loaded before dependent
  // code is executed
  script = document.createElement('script');
  script.src = 'sizzle.min.js';
  script.onload = function() {
    sizzle_loaded = true;
    callback.apply(window,[module_name].concat(args)); //Add the module_name as first argument and then every other argument specified by the user
  };
  script.onreadystatechange = function() {
    if ((script.readyState === 'loaded' || script.readyState === 'complete') &&
        !sizzle_loaded) {
      sizzle_loaded = true;
      callback(module_name);
    }
  };

  // append script to the document
  document.getElementsByTagName('head')[0].appendChild(script);

}

Then as third argument of load_sizzle you can pass an array of extra arguments for the function.

然后作为load_sizzle的第三个参数,您可以传递函数的额外参数数组。

You can also improve the code with this:

您还可以通过以下方式改进代码:

function load_sizzle(module_name, callback,args,bind) {

  var script, args=args || [],bind=bind || window;

  // load Sizzle script and set up 'onload' and 'onreadystatechange' event
  // handlers to ensure that external script is loaded before dependent
  // code is executed
  script = document.createElement('script');
  script.src = 'sizzle.min.js';
  script.onload = function() {
    sizzle_loaded = true;
    callback.apply(bind,[module_name].concat(args)); //Add the module_name as first argument and then every other argument specified by the user
  };
  script.onreadystatechange = function() {
    if ((script.readyState === 'loaded' || script.readyState === 'complete') &&
        !sizzle_loaded) {
      sizzle_loaded = true;
      callback(module_name);
    }
  };

  // append script to the document
  document.getElementsByTagName('head')[0].appendChild(script);

}

In this way the argument number 4 (if specified) can be an object that will be the "this" inside the callback that you pass.

这样,参数4(如果指定的话)可以是您通过的回调中的“this”对象。