I am really new to funcitonal paradigm and I have a hard time understanding what is going on with the following snippet.
const countDown = (val, cb, delay = 1000) => {
cb(val, delay);
return (val > 0) ? setTimeout(() => countDown(val - 1, cb, delay), delay) : val;
}
countDown(5, console.log, 100)
Why the following doesn't work, given the fact that setTimeout takes a function as an argument?
const countDown = (val, cb, delay = 1000) => {
cb(val, delay);
return (val > 0) ? setTimeout(countDown(val - 1, cb, delay), delay) : val;
}
countDown(5, console.log, 100)
2 Answers 2
The setTimeout function takes a callback function as first argument. So in your example you need to pass a function definition and not the function call.
this is a function definition:
() => countDown(val - 1, cb, delay), delay)
or the same without arrow functions:
function() { countDown(val - 1, cb, delay), delay) }
while this is a function call:
countDown(val - 1, cb, delay)
Comments
This is another way you can look at your problem. countDown is concerned with repeatedly calling a function, decrementing a counter, and inserting some time in between the function calls – that's a lot for one function.
I'll be abstracting some of this complexity away with delay and effect and repeat. You'll notice that countDown requires zero logic once we've abstracted to this point – this is sometimes why people say functional programs can take on a declarative resemblance.
const delay = ms => x =>
new Promise (r => setTimeout (r, ms, x))
const effect = f => x =>
(f (x), x)
const repeat = n => f => x =>
n === 0 ? x : repeat (n - 1) (f) (f (x))
const countDown = (x, ms, f) =>
repeat (x)
(p => p.then (effect (f)) .then (delay (ms)) .then (x => x - 1))
(Promise.resolve (x))
countDown (5, 1000, console.log)
.then (x => console.log ('done', x))
Comments
Explore related questions
See similar questions with these tags.
countDown. That's why the arrow function exists on the first example.countDownis a function, butcountDown(val - 1, cb, delay)is not.