我对功能范式很陌生,我很难理解以下代码段的内容。
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)
考虑到setTimeout
将函数作为参数这一事实,以下为什么不起作用?
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)
答案 0 :(得分:1)
setTimeout
函数将回调函数作为第一个参数。因此,在您的示例中,您需要传递函数定义而不是函数调用。
这是一个函数定义:
() => countDown(val - 1, cb, delay), delay)
或没有箭头功能的相同:
function() { countDown(val - 1, cb, delay), delay) }
虽然这是一个函数调用:
countDown(val - 1, cb, delay)
答案 1 :(得分:0)
这是您可以查看问题的另一种方式。 countDown
关注的是重复调用一个函数,递减一个计数器,并在函数调用之间插入一些时间 - 这是一个函数的 lot 。
我将使用delay
和effect
以及repeat
来抽象一些复杂性。一旦我们抽象到这一点,你会注意到countDown
需要零逻辑 - 这有时候人们说功能程序可以采用声明性的相似性。
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))