使用setTimeout进行Javascript回调

时间:2017-08-10 17:59:59

标签: javascript functional-programming 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)

考虑到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)

2 个答案:

答案 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

我将使用delayeffect以及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))