通过fn.apply或fn.bind将函数传递给setTimeout

Pass function to setTimeout via fn.apply or fn.bind

本文关键字:fn setTimeout 函数 apply bind 通过      更新时间:2023-09-26

为了限制对API的请求,我制作了一个方法,每个间隔只允许一定数量的请求。

它是有效的,但我想对setTimeout部分进行润色。

我试过setTimeout(fn.apply, self.sleepTime(), null, fn_arguments)setTimeout(fn.bind(fn_arguments), self.sleepTime())

所以我想知道的是,我是否可以将fn传递到setTimeout,而不将其封装在function中?

function (fn) {
  var self = this;
  return function () {
    var fn_arguments = arguments;
    setTimeout(function () {
      fn.apply(null, fn_arguments);
    }, self.sleepTime());
  };
};

测试:

var args;
function fn () {
  document.write(JSON.stringify(arguments), ' ~ ', JSON.stringify(arguments) === JSON.stringify(args));
  document.write('<br>');
}
(function() {
  args = arguments;
  fn('hello', 'world'); // { '0': 'hello', '1': 'world' }  ✓
  fn.bind.apply(fn, [null].concat(arguments))(); // { '0': { '0': 'hello', '1': 'world' } }
  fn.bind.apply(fn, Array.prototype.slice.call(arguments))(); // { '0': 'world' }
  fn.bind.apply(fn, [null].concat(Array.prototype.slice.call(arguments)))(); // { '0': 'hello', '1': 'world' }  ✓
}('hello', 'world'));

关闭!你只需要结合第二步和第三步:

fn.bind.apply(fn, [null].concat(Array.prototype.slice.call(arguments)))();

您可以使用bind创建一个包含函数参数的函数,并在setTimout调用中使用它。但是,bind不接受单个参数数组,而是接受多个逗号分隔的参数。要解决此问题,可以在绑定函数上调用apply,如下所示:

setTimeout(fn.bind.apply(fn, [null].concat(fn_arguments)), self.sleepTime())

edit:您必须确保fn_arguments是一个数组,例如通过var fn_arguments = Array.prototype.slice.call(arguments); 转换arguments对象