2

This is a simple version of what I'm trying to do in my application. I have an if statement which evaluates the result of a function call and then populates an array if the statement comes back as true. AFTER the if statement is completely finished, I want to run some more code such as the console.log as seen below.

I understand that the if's evaluation is taking too long to finish and javascript just continues to the console.log because of its asynchronicity. How do I make the code wait for the if statement to complete?

var tabs = [];

if (isTrue()) {
    tabs.push('some string');
}

console.log(tabs[1]);

function isTrue() {
    setTimeout(function() {
        return true;
    }, 500)
}
Ben
  • 33
  • 2

4 Answers4

1

You could pass a callback to the isTrue() function, something like:

function isTrue(_callback) {
    setTimeout(function() {
        // code here

        // Call the callback when done
        if (typeof(_callback) === 'function')
            _callback(tabs);
    });
}

function showTabs(tabs) {
    console.log(tabs[1]);
}

isTrue(showTabs);

Ought to work.

Nunchy
  • 920
  • 5
  • 11
1

Using modern javascript, you can achieve that using promises and async/await:

const isTrue = () => new Promise(resolve => setTimeout(resolve, 500, true));

// you can only use `await` inside an `async` function
async function main() {
  // better use `let` instead of `var` since `let` is block scoped,
  // see:
  // <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let>

  let tabs = [];

  if (await isTrue()) {
    tabs.push('some string');
  }

  // array's index start by 0, not 1
  console.log(tabs[0]);
}

main();

(this code also use arrow functions for isTrue.)

ZER0
  • 22,173
  • 4
  • 45
  • 51
1

You can just wrap your code in a Promise and consume the returned values by calling then on it:

var tabs = [];
isTrue().then(res => {
  if (res) {
    tabs.push('some string');
  }
  return tabs;
}).then(arr => {
  console.log(arr);
});



function isTrue() {
  //Just wrap your existing code in a Promise constructor
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      //Pass whatever value you want to consume later to resolve
      resolve(true);
    }, 500)
  });
}
Tom O.
  • 5,133
  • 2
  • 19
  • 33
0

isTrue() returns undefined. The return true inside of the setTimeout callback will return back to the timeout call, not to the isTrue() call. The code executes immeadiately and there is no asynchronity involved (except for that timer that does nothing).

Jonas Wilms
  • 106,571
  • 13
  • 98
  • 120