8

Let's say there is a code in place 2

var place2IsReady = true;

In place 1 I need to implement the logic below :

Once place2IsReady value was changed (to true) then display alert('ready!');

Notes:

  • place2IsReady variable is not available in the scope of place 1.
  • the code from place 1 gets executed before place 2 gets executed (or there is a race condition).

Solution 1

I believe I can use window.place2IsReady instead and use setTimeout/setInterval in place 1 until I get window.place2IsReady === true.

Any better options? Using Listeners? On the variable change?

P.S. I need to track only first possible change of place2IsReady.

Is there a better way? Thank you.

5
  • Are you using some framework? Commented Jan 28, 2021 at 13:14
  • Variables don't do any sort of notification on change. You either have to continually poll and check if the variable changed or actually use some pattern or library that will let you track changes. Commented Jan 28, 2021 at 13:15
  • 1
    @distante My preferable answer: No. JS + TS + jQuery in some places. Vanilla JS solution is preferable. Commented Jan 28, 2021 at 13:17
  • "place2IsReady" can be an object instead of a Boolean value? Commented Jan 28, 2021 at 13:24
  • Not sure what exactly you are looking for, but you may use javascript.info/property-accessors getter/setter to do dependent operation on execution of setter's call. Commented Jan 28, 2021 at 13:30

2 Answers 2

5

You can create a listener for the variable change using setTimeout, something like:

let place2IsReady = false;

setReadyListener();

// testing wait 2 seconds to set place2IsReady to true
// so: an alert should occur after 2 seconds
setTimeout(() => place2IsReady = true, 2000);

function setReadyListener() {
  const readyListener = () => {
    if (place2IsReady) {
      return alert("Ready!");
    }
    return setTimeout(readyListener, 250);
  };
  readyListener();
}

A more generic listener 'factory' could be:

let place2IsReady = false;
let fromObj = {
  place2IsReady: "busy",
  done() { this.place2IsReady = "done"; },
};
const listen = changeListenerFactory();

listen(
  () => place2IsReady, 
  () => console.log("place2IsReady") );
listen(
  () => fromObj.place2IsReady === "done", 
  () => console.log("formObj.place2IsReady done!") );
  
console.log("Listening...");

// test change variables with listeners
setTimeout(() => place2IsReady = true, 1000);
setTimeout(() => fromObj.done(), 3000);

function changeListenerFactory() {
  const readyListener = (condition, callback, delay) => {
    if (!condition || typeof condition !== "function") { return true; }
    if (condition()) {
      return callback();
    }
    setTimeout(() => readyListener(condition, callback, delay), delay);
  };
  
  return (condition, callback = () => {}, delay = 250) => 
    readyListener(condition, callback, delay);
}

Or maybe using a Proxy (with a set trap) works for you

const readyState = new Proxy({ ready: false }, { 
  set (target, prop, val) {
    console.log(`readyState.ready changed from ${target[prop]} to ${val}`);
    target[prop] = val;
  }
});

console.log("Waiting for changes ...");
setTimeout(() => readyState.ready = true, 2000);

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

3 Comments

Thank you. Could you please explain why place2IsReady = true; place2IsReady = false; place2IsReady = true; doesn't display the second alert?
I could, if I understood what you meant
@Kooilnc, got it, thank you, it was executed only once.
1

Assuming you can replace place2IsReady with an object:

place2IsReady = {
  state: false,
  set ready(value) {
      this.state = value
      state && place_1_call()
  },
  get ready() { 
    return state
  }
}

place_1_call = () => {
  alert('ready')
}

place2IsReady.ready = true

Comments

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.