Delaying decorator
중요도: 5
Create a decorator delay(f, ms)
that delays each call of f
by ms
milliseconds.
For instance:
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
In other words, delay(f, ms)
returns a “delayed by ms
” variant of f
.
In the code above, f
is a function of a single argument, but your solution should pass all arguments and the context this
.
The solution:
function
delay
(
f,
ms
)
{
return
function
(
)
{
setTimeout
(
(
)
=>
f
.
apply
(
this
,
arguments)
,
ms)
;
}
;
}
let
f1000 =
delay
(
alert,
1000
)
;
f1000
(
"test"
)
;
// shows "test" after 1000ms
Please note how an arrow function is used here. As we know, arrow functions do not have own this
and arguments
, so f.apply(this, arguments)
takes this
and arguments
from the wrapper.
If we pass a regular function, setTimeout
would call it without arguments and this=window
(assuming we’re in the browser).
We still can pass the right this
by using an intermediate variable, but that’s a little bit more cumbersome:
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)
;
}
;
}