简体   繁体   中英

Defer A Function for 24 Hours

I'm trying to make a function not work temporarily(24 hours) after clicked once.

I tried wrapping the whole thing in a setTimeout() function setting the ms count to a day which is 86400000.

(See output here )

$('.dates').click(function() {
  var rand = Math.floor(Math.random() * 100 + 1);
  var flows = ["flowOne", "flowTwo", "flowThree"];
  var colors = ["colOne", "colTwo", "colThree", "colFour", "colFive", "colSix"];
  var timing = (Math.random() * (1.3 - 0.3) + 1.6).toFixed(1);
  // Animate Particle
  $('<div class="particle part-' + rand + ' ' + colors[Math.floor(Math.random() * 6)] + '" style="font-size:' + Math.floor(Math.random() * (30 - 22) + 22) + 'px;"><i class="fa fa-heart-o"></i><i class="fa fa-heart"></i></div>').appendTo('.particle-box').css({
    animation: "" + flows[Math.floor(Math.random() * 3)] + " " + timing + "s linear"
  });
  $('.part-' + rand).show();
  // Remove Particle
  setTimeout(function() {
    $('.part-' + rand).remove();
  }, timing * 1000 - 100);
  $('#output').html(function(i, val) {
    return parseInt(val, 10) + 1;
    console.log(val);
  });
  return false;
});

Is there something I'm missing?

How do I defer the function so that it can only be invoked every 24 hours?

In order to prevent a function from executing, without changing how the rest of your application interacts with said function, you need to use some kind of flag or boolean condition.

For example:

$('.dates').click(function() {
  if (!isActive) {
    return;
  }

  // rest of your code
});

Now, the easiest way to calculate 24 hours from the current time is probably by using Date.now to retrieve the current time in milliseconds then add 24 hours, in milliseconds, to that value.

// Calculate 24 hours in milliseconds
var second = 1000;
var minute = 60 * second;
var hour = 60 * minute;
var day = 24 * hour;

var now = Date.now();
var tomorrow = now + day;

Given how long you want to wait, you'll likely want to save this in localStorage :

localStorage.setItem('next-active-time', tomorrow);

Now all you have to do is change how you activate the function. Rather than using a simple flag, check for the next value in local storage and only activate if it

  • has not been created yet
  • the current time is greater than or equal to that time
$('.dates').click(function() {
  // default to 0 when it hasn't been set
  var nextActiveTime = localStorage.getItem('next-active-time') || 0;
  if (Date.now() < nextActiveTime) {
    return;
  }

  // rest of your code
  // make sure to update local storage at this point
});

In theory, you could accomplish what you are looking to do with lodash's throttle (or similar implementation), but it looks to me like you are programming in the browser, so enforcing this 24 hour rule is impossible (the user can refresh the page at anytime). With that said:

  • If you don't care about enforcing it, get a copy of lodash's throttle .
  • If you just care about partially enforcing it (it'll only be enforced in the current browser), you could use localStorage (I recommend this library), or if you're only supporting latest browsers, I recommend using indexedDB with this wrapper.
  • If you care about truly enforcing it (across browsers and devices), you would need to authenticate the user and have a session keeping track on the backend. This route is beyond the scope of this question, so I'll end here.

I hope that clears things up a bit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM