0

I want to get a js variable as soon as it's defined.

I tried this:

function waitForCondition(variable) {
    function waitFor(result) {
        if (result) {
            return result;
        }
        return new Promise((resolve) => setTimeout(resolve, 100))
            .then(() => Promise.resolve([variable]))
            .then((res) => waitFor(res));
    }
    return waitFor();
}

But this will return even on false e.g.:

let variable = false;
waitForCondition('variable').then((res) => { console.log(variable); });
variable = 123;

How to return the variable once it's set and not false?

  • Your example generates an error because you are declaring the variable twice. However, if you remove the second `let` and run it, it console.logs 123. – imvain2 Jul 25 '23 at 20:28
  • I created a fiddle instead of changing your code https://jsfiddle.net/8k6jw5pv/ – imvain2 Jul 25 '23 at 20:29
  • 3
    I would suggest refactoring your code so that it doesn't depend on polling to know when a variable has changed. This sounds like an [XY Problem](https://xyproblem.info). – Heretic Monkey Jul 25 '23 at 20:29
  • This has literally nothing to do with the linked question – Christian Vincenzo Traina Jul 25 '23 at 20:30
  • Did you mean `return waitFor()` or `return waitFor`? I'm assuming that `waitForCondition(x)` is supposed to return the `waitFor` function, not actually call it. – jarmod Jul 25 '23 at 20:31
  • That promise will resolve after 100ms, then resolve with the value of the variable in an array, then call `waitFor` with the value of the variable in an array, which will always be truthy. Remove the square brackets, like `Promise.resolve(variable)`. – Heretic Monkey Jul 25 '23 at 20:35
  • 1
    Where is `variable` modified? What holds you back from calling a function (like `console.log`) when you do that? – trincot Jul 25 '23 at 20:43
  • Did you mean to use `window[variable]` or something like that, instead of the array literal `[variable]` (which is always a truthy value)? – Bergi Jul 25 '23 at 21:31

2 Answers2

1

Primitive variables are passed by value in JavaScript, so you will never know when variable changes when you simply pass its value in.

If you were to use a global value (in this case, a property of window), you could just check that each time you polling interval passes. You could then broaden the utility of the function by allowing the user to specify the name of the variable to track.

That said, this is all a long, complicated, and less well performing way of avoiding writing code in the place that actually changes the variable.

function waitForCondition(name) {
  function waitFor(result) {
    console.log(`result: ${result}`);
    if (result) {
      return Promise.resolve(result);
    }
    return new Promise((resolve) => setTimeout(resolve, 100))
      .then(() => Promise.resolve(window[name]))
      .then((res) => waitFor(res));
  }
  return waitFor();
}

window.variable = false;
waitForCondition('variable').then((res) => {
  console.log(res);
});
setTimeout(() => window.variable = 123, 500);
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
0

You are using the let statement twice

When you initialize a variable (let variable = false;) you need to use the let keyword. When reassigning a value (the variable has already been initialized), you don't use the let keyword.

What ever you do to set it could be done in the promise, then you could use a .then method to use the set variable.

WOWOW
  • 91
  • 8