延迟装饰器
重要性: 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
请注意这里是如何使用箭头函数。正如我们所知,箭头函数没有自己的 this
和 arguments
,所以 f.apply(this, arguments)
从包装器中获取 this
和 arguments
。
如果我们传递一个普通函数,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);
};
}