延时装饰器
重要程度: 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
注意这里是如何使用箭头函数的。我们知道,箭头函数没有自己的 this
和 arguments
,所以 f.apply(this, arguments)
从包装器中获取 this
和 arguments
。
如果我们传递一个常规函数,setTimeout
将调用它且不带参数,并且 this=window
(假设我们在浏览器环境)。
我们仍然可以通过使用中间变量来传递正确的 this
,但这有点麻烦:
function delay(f, ms) {
return function(...args) {
let savedThis = this; // 将 this 存储到中间变量
setTimeout(function() {
f.apply(savedThis, args); // 在这儿使用它
}, ms);
};
}