回到课程

延时装饰器

重要程度: 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); }; }

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