在同步时尚中使用setTimeout处理递归函数

时间:2018-04-14 03:28:18

标签: javascript

我有以下功能,希望能够在此功能之外调用另一个功能,并且只有在此功能完成后才能运行。我知道setTimeout是导致异步行为的原因。我已经尝试过promises,但无法弄清楚如何将promise与setTimeout和递归操作结合使用。

这个函数的基本思想是花费一些时间,我们会说10秒并倒数到0.一旦倒计时到零,那么理想情况下下一个函数会运行。 setTimeout用于每1秒(1000毫秒)递归调用函数

const countDown = () => {
    if (seconds > 0) displayTime(seconds, 'second', '--');
    else if (minutes > 0) {
        displayTime(minutes, 'minute', '--');
        displayTime(59, 'second');
    }
    else if (hours > 0) {
        displayTime(hours, 'hour', '--');
        displayTime(59, 'minute');
    }

    seconds = parseInt(secondTwo.innerHTML + secondOne.innerHTML);
    minutes = parseInt(minuteTwo.innerHTML + minuteOne.innerHTML);
    hours = parseInt(hourTwo.innerHTML + hourOne.innerHTML);

    if (seconds === 0 && minutes === 0 && hours === 0) {
        audio.play();
        endTimer();
    }

    countDownId = setTimeout(() => {
        countDown();
    }, 1000);
}

如果您有任何疑问或需要澄清,请告诉我们!提前谢谢!

1 个答案:

答案 0 :(得分:0)

如果你传入小时,分钟和秒以及回调更新功能,也许倒计时会更简单。倒计时将每秒调用此函数,其值为小时,分钟和秒。

倒计时可以返回在倒计时结束时将解决的承诺:



const later = time => new Promise(
  resolve=>setTimeout(
    ()=>resolve(),
    time
  )
);
const getHours = timeLeft => Math.floor(timeLeft/3600000);
const getMinutes = timeLeft => Math.floor((timeLeft%3600000)/60000);
const getSeconds = timeLeft => Math.floor((timeLeft%60000)/1000);
const countDown = (hours,minutes,seconds) => updateFunction => {
  const start = Date.now();
  const total = (hours*3600000)+(minutes*60000)+(seconds*1000);
  const recur = () => {
    const timePassed = Date.now() - start;
    if(timePassed>=total){
      updateFunction(0,0,0);//call your callback
      return Promise.resolve("what you want to return");//resolve the returned promise to a value
    }
    const secondsLeft = getSeconds(total-timePassed);
    const minutesLeft = getMinutes(total-timePassed);
    const hoursLeft = getHours(total-timePassed);
    if(minutesLeft<0){
      debugger;
    }
    //call your callback
    updateFunction(
      hoursLeft,
      minutesLeft,
      secondsLeft
    );
    return later(1000)
    .then(
      ()=>recur()//recursively call itself
    )
  }
  return recur();
}
countDown(0,2,0)(
  (h,m,s)=>console.log("hours:",h,"minutes:",m,"seconds:",s)
)
.then(
  ()=>console.log("countdown is done")
);
&#13;
&#13;
&#13;