Home > Enterprise >  how do i stop Timeout from running if condition changes/updates?
how do i stop Timeout from running if condition changes/updates?

Time:05-02

code:

const isEnd = false; // Whenever event triggers the value will be false.

if (isEnd) {
console.log('Manual End')
} else {
setTimeout(() => {
console.log('Automatic End')
}, 30000);
}

Issue:

  • This is event, so when the event triggers isEnd value will be false and when event triggers it has 30 seconds to update value to true.
  • isEnd value can be changed to true, Anytime by the user/me in running app or without restarting.
  • If isEnd values changes to true in a given time (30 seconds) I want to log manual end and remove setTimeout and don't log amything inside setTimeout function.

I tried until now:

  • tried if/else, switch, while, do while.
  • tried to clearTimeout and a lot different ways but can't remove setTimeout
import { setTimeout as wait } from 'node:timers/promises';

  let timerId;
  switch (isEnded) {
    case true:
      console.log('Manual Ended');

      clearTimeout(timerId);
      break;
    case false:
      clearTimeout(timerId);
      timerId = wait(30000).then(() => {
        console.log('Automatic Ended');
      });
      break;
  }

excepted:

  • if condition updates log manual End
  • if condition doesn't changes it should only log Automatic End
  • should log only any one of two logs.

CodePudding user response:

instead of trying to trigger changes in the value of isEnd you can try a different approach,

you can directly clearTimeOut whenever you or the user change the value of isEnd

for example instead of doing this

const isEnd = false 
let timerId;

buttn.addEventListener("click", () => {
  isEnd = true
})



if (isEnd) {
  console.log('Manual End')
  clearTimeOut(timerId)
} else {
timerId = setTimeout(() => {
  console.log('Automatic End')
}, 30000);
}

do this

let timerId =  setTimeout(automaticEnd, 30000);
// when the user make a manual break 
cancelButton.addEventListener("click", () => {
  manualEnd()
})



function automaticEnd() {
  console.log('Automatic End')
}

function manualEnd() {
  clearTimeOut(timerId)
  console.log("manualEnd")
}

CodePudding user response:

You could try a somehow more complex but interesting and elegant approach, using an object structure for your condition isEnd, and using object getters and setters to subscribe to a custom listener for object property changes:

This works perfectly in browser console (you can launch the snippet), should work in Node as well:

// Object of your condition
const isEnd = {
  _value: false, // this is the value of the condition
  valueListener: function(val) {}, // defining a generic listener

  // getter
  get value() {
    return this._value;
  },

  // setter
  set value(val) {
    this._value = val;
    this.valueListener(val); // when changing the value, the function valueListener is called with the new value set
  },

  // method to pass an actual listener function to valueListener property
  listenTo: function(listener) {
    this.valueListener = listener;
  }
};

console.log("START: isEnd has a value of: "   isEnd.value);


// timer of 20 seconds
const timer = setTimeout(() => {
  console.log('Timer expired');
}, 20000)

// you subscribe to the isEnd.value change, passing an actual listener function
// this function should contain the logic to execute
// based on the new condition value
// (like clearing the timer)
isEnd.listenTo(function(val) {
  console.log('new value for isEnd is now: '   val);

  if (val === true) {
    if (timer) {
      clearTimeout(timer);
      console.log('timer cleared!');
    }
  }

  if (val === false) {
    console.log('HEY... false again!');
  }
})

// timer of 5 seconds that simulates
// the condition changing after 5 seconds
setTimeout(function() {
  isEnd.value = true;
}, 5000)

// timer of 10 seconds that simulates
// the condition changing after
// another 5 seconds
setTimeout(function() {
  isEnd.value = false;
}, 10000)

  • Related