【问题标题】:Decrement a variable once a day - Javascript每天减少一次变量 - Javascript
【发布时间】:2016-04-28 12:18:18
【问题描述】:

我正在尝试每天减少一次变量。我为此编写了以下代码。

var counter = 10; //any value

setInterval(function() {

  counter = counter - 1;

}, 86400000);

是否有更好或更有效的方法来实现相同的目标?

P.S : - 我不想使用任何库。

【问题讨论】:

  • 嗯?什么图书馆?您当前的代码没有使用...
  • 我只是想知道是否有更好的方法来编写这段代码?以这种更好的方式,我不想使用任何库,例如时刻。这就是我的意思。抱歉,不清楚
  • @Jeroen 他可能想要一种更好的方法来解决这个问题,而无需使用库。他并不是说他现在正在使用一个,只是他不想在解决方案中使用:-)
  • 你当前代码的问题是运行几千年后它会漂移......哼——不好,不好。

标签: javascript


【解决方案1】:

我看到你唯一想念的是设置counter变量的初始值。
我会写:

var counter = 1000; // or any useful value

setInterval(function() {
  --counter;
}, 24 * 60 * 60 * 1000); // this is more self-explanatory than 86400000, and, being evaluated just once, it will have a tiny effect on the performace of the script

【讨论】:

  • 感谢 24*60*60*1000 部分。
  • :-) 我声称清晰比速度更可取(当速度增益如此之小时)。
【解决方案2】:

我认为您的写作方式没有任何问题。您使用区间,好的,但这并不是您设置变量值时可能做的最糟糕的事情。

您可能会想到另一种解决方案,该解决方案具有返回当前计数器的函数。

var initialValue = 20000;

function getCounter() {
  return initialValue - Math.floor(Date.now() / 1000 / 60 / 60 / 24);
}

console.log(getCounter());

不同之处在于它采用从 UNIX 时间开始的当前天数。每天天数都会增加,所以函数的结果会减少1。

但我仍然没有看到这个解决方案比你的解决方案更好。

【讨论】:

    【解决方案3】:

    我不完全确定为什么,但是像这样使用setInterval 让我很不舒服。

    如果我需要这个,我会使用类似这样的方法:

    var counter = 10;
    var timeout = new Date();
    setInterval(function(){
      if(new Date() >= timeout)
      {
        --counter; // the action to perform
        timeout = new Date(timeout.getTime() + 86400000); // update the timeout to the next time you want the action performed
      }
      console.log(counter);
    },1000); // every second is probably way more frequent than necessary for this scenario but I think is a decent default in general
    

    这允许的一件事是,例如,将下一次超时设置为明天的午夜,而不是锁定为“自上次执行以来的 X 秒”。关键是控制反转——动作本身现在可以决定下一次运行的时间。

    虽然我可能会抽象出接受开始、间隔和动作的接口背后的细节。

    【讨论】:

      【解决方案4】:

      在我看来,最大的问题是你必须让这个 JS 进程连续运行几天才能让它完成你需要的工作。世界并不完美,以至于不需要偶尔重启……包括普通的 JS 进程。

      我个人会存储我的起点的时间戳,然后(每当我需要知道已经过去了多少时间时)获取一个新的时间戳并使用它来计算它已经过了多少天。这样,即使有什么事情打断了我的进程,我仍然可以在我开始的地方。

      【讨论】:

        【解决方案5】:

        也许使用 window.localStorage 保存最后一次,如果大于 60*60*24(一天中的秒数),则将最后一次设置为今天早上/现在/1:00,然后减小该值并保存它。

        例子:

        var d = new Date();
        var mins = -(1+d.getHours())*60+d.getMinutes();
        var secs = mins*60+d.getSeconds(); // total seconds passed today from 1:00
        var now = d.getCurrentTime():
        var lastCheck = localStorage.getItem("lastCheck");
        if (!lastCheck)
        {
            localStorage.saveItem("lastCheck",now-secs); // beginning of today
        }
        var dayPassed = now - lastCheck > 24*60*60; // change to see if a day has passed
        if (dayPassed)
        {
            // save seconds
            localStorage.setItem("counter",localStorage.getItem("counter")-1);
            localStorage.saveItem("lastCheck",now-secs); // beginning of today
        }
        

        【讨论】:

          【解决方案6】:

          检查自特定日期以来经过了多少天并从计数器中减少该天数对我来说更有意义。主要是因为我不希望任何人在不需要或想要连续几天重新加载的情况下打开同一页面。我会这样做:

          counter = 365; // original counter
          var start = new Date(2016, 03, 20); // original date
          var now = new Date();
          var days = Math.floor(Math.abs(start.getTime()-now.getTime())/(24*60*60*1000))
          counter -= days;
          

          这样每次您访问该页面时,它都会正确递减。请注意,这忽略了闰日或时区的任何问题。上面的例子对我来说会有一个 360 的计数器。然后,如果您确实希望它会打开几天,请使用以下命令自动重新加载:

          self.setTimeout(function(){document.location.reload()}, 86400000);
          

          【讨论】:

          • 它可能是服务器端的 javascript,而不是客户端的 html 页面。
          • now = parseInt(d.getFullYear()+''+(d.getMonth()+1)+''+d.getDate()); - 这应该是错误的。
          • “应该”是什么意思?它以整数形式返回当前日期,例如 2016423。
          • 不确定您是否知道自己在做什么,因为我看到您在 setTimeout 内调用字符串文字...
          • 我也不确定您是否知道 getMonth() 究竟返回了什么,以及当月份返回为二时,您计划如何从任何(奇怪的)日期可靠地减去 2016423数字月份...
          猜你喜欢
          • 2015-10-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-19
          • 1970-01-01
          • 1970-01-01
          • 2016-09-14
          相关资源
          最近更新 更多