返回课程

延迟装饰器

重要性: 5

创建一个装饰器 delay(f, ms),它将 f 的每次调用延迟 ms 毫秒。

例如

function f(x) {
  alert(x);
}

// create wrappers
let f1000 = delay(f, 1000);
let f1500 = delay(f, 1500);

f1000("test"); // shows "test" after 1000ms
f1500("test"); // shows "test" after 1500ms

换句话说,delay(f, ms) 返回 f 的“延迟 ms”变体。

在上面的代码中,f 是一个只有一个参数的函数,但您的解决方案应该传递所有参数和上下文 this

打开一个带有测试的沙箱。

解决方案

function delay(f, ms) {

  return function() {
    setTimeout(() => f.apply(this, arguments), ms);
  };

}

let f1000 = delay(alert, 1000);

f1000("test"); // shows "test" after 1000ms

请注意这里是如何使用箭头函数。正如我们所知,箭头函数没有自己的 thisarguments,所以 f.apply(this, arguments) 从包装器中获取 thisarguments

如果我们传递一个普通函数,setTimeout 会在没有参数的情况下调用它,并且 this=window(假设我们在浏览器中)。

我们仍然可以通过使用中间变量来传递正确的 this,但这有点麻烦

function delay(f, ms) {

  return function(...args) {
    let savedThis = this; // store this into an intermediate variable
    setTimeout(function() {
      f.apply(savedThis, args); // use it here
    }, ms);
  };

}

在沙箱中打开带有测试的解决方案。