0

Sorry this is going to take a bit of explaining so you know what I'm trying to do here...

I'm having trouble with a timer function. Basically when the user hits the page, an Ajax request is made, the result of which starts a timer function. They have a certain amount of time in which to make a payment (this is a block chain based payment app, payment is made via an external wallet - no user input is required on the payment page at all, no buttons to click etc). If the timer runs out the payment box resets.

But if the persistent Ajax calls running in the background find the users payment on the block chain I need to kill the timer as it is no longer required, but I need to keep the payment box open while the confirmations are being monitored until the transaction is complete.

The trouble is I can't alter the already running timer function. I've tried every way possible I could think of but nothing stops the original function from running and ultimately resetting the payment box while the transaction is ongoing (waiting for confirmations).

I have been reading about wrapping the timer function in an object and adding a listener but everything I found seemed really confusing to me.

Below is the relevant code.

The function that starts the timer is being started by the Ajax response from another function...

myTimer(expiry);

The expiry variable being passed is vital as it sets an intial on / off state for the timer (whether to display it or not from the first response). So I need to keep that.

This is the timer function...

function myTimer(expiry) {

// If expiry set to 0 don't use the timer
if (expiry === 0) {
  $('#timer').hide();
  return;
}

var start = new Date();
var timeoutVal = Math.floor(expiry/100);
animateUpdate();

function updateProgress(percentage) {
  $('#timerInner').css("width", percentage + "%");
}

function animateUpdate() {

    var now = new Date();
    var timeDiff = now.getTime() - start.getTime();
    var perc = Math.round((timeDiff/expiry)*100);

    if (perc <= 100) {
      updateProgress(perc);
      setTimeout(animateUpdate, timeoutVal);

      } else {

        // Timer expired, clear box and show buy button again
        $("#paymentWrap").empty();
        $("#btn-Pay").show();
        $("#btn-Pay").prop("disabled", false);
        return;
      } 
    }

}
}

This is the part that I need to "kill" on demand via another function coming from another Ajax response...

// Timer expired, clear box and show buy button again
$("#paymentWrap").empty();
$("#btn-Pay").show();
$("#btn-Pay").prop("disabled", false);
return;

Can somebody explain how I can add a variable listener to this function (maybe by creating it as an object?) so that I can change the chunk of code that triggers the bit above to include a new var called cancelled that can be updated elsewhere in the script WHILE this function is running.

if (perc <= 100) {
      updateProgress(perc);
      setTimeout(animateUpdate, timeoutVal);

         if (cancelled === true) {
            // Hide the timer div and kill the timer function
            $("#timer").hide();
            return;
         }

      } else {

        // Timer expired, clear box and show buy button again
        .......

I know this was really long winded, apologies upfront, but thanks for reading and looking forward to any help you can offer.

Cheers!

3
  • 1
    You can set setTimeout call as a global variable and use clearTimeout() var timer; timer = setTimeout(animateUpdate, timeoutVal); clearTimeout(timer) Commented Nov 4, 2017 at 23:20
  • But will my other function be able to read the clearTimeout(timer) function or will it throw an undefined? Commented Nov 4, 2017 at 23:24
  • Wow, this actually worked. You wouldn't believe how many houses I ran around trying different things to make this happen. You did it with 3 lines of code! Thanks man! Commented Nov 4, 2017 at 23:39

1 Answer 1

1

You can define a global variable to reference setTimeout() call and use cleaTimeout()

let timer = null;

let then_ = new Date().getTime() + 10000;

function fn() {
  timer = setTimeout(function() {
    console.log("doing stuff at " + new Date() 
    , "time remaining to do stuff:", then_ - new Date().getTime());
    if (new Date().getTime() < then_) {
      fn()
    } else {
      done()
    }
  }, 1000)
}

function done() {
  clearTimeout(timer);
  timer = null;
  console.log("done doing stuff at " + new Date());
}

document.querySelector("button")
  .onclick = function() {
    if (timer) {
      done()
    } else {
      this.onclick = null;
    }
  }

fn();
<button>clear timer</button>

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the expansion but simply adding your original 3 lines of code did the trick for me!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.