回到课程

延迟装饰器

重要程度: 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"); // 在 1000 ms 后展示 "test"
f1500("test"); // 在 1500 ms 后展示 "test"

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

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

打开带有测试的沙箱。

解决方案:

function delay(f, ms) {

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

}

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

如果我们传递一个常规函数,setTimeout 将调用它且不带参数和 this=window(在浏览器中),所以我们需要编写更多代码来从包装器传递它们:

function delay(f, ms) {

  // added variables to pass this and arguments from the wrapper inside setTimeout
  return function(...args) {
    let savedThis = this;
    setTimeout(function() {
      f.apply(savedThis, args);
    }, ms);
  };

}

使用沙箱的测试功能打开解决方案。