回到课程

延时装饰器

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

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

在上面的代码中,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; // 将 this 存储到中间变量
    setTimeout(function() {
      f.apply(savedThis, args); // 在这儿使用它
    }, ms);
  };

}

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