0

Need to make a function wait for 4 seconds before returning a string, but not having any luck. Basically this is what I'm trying to do:

function myFunction(){
 var str = '';
// DO SOMEHITNG HERE so when it's done the finally return "I'm done"

 return "I'm done";
}

This is what I currently have (What am I missing), but I'm also down for any other way to do this. Thanks in advance!

function myFunction(){
 var counter = 0;
 var execute =  setInterval(print,  1000);

 function print(){
    document.write("Counting" + counter + "<br/>");
    ++counter;

    if(counter < 5){
        clearInterval(execute);
         str = "I'm done";
    }
 }

  return str; // Here I want to return "I'm done"
}
Devmix
  • 1,599
  • 5
  • 36
  • 73
  • 3
    Try setTimeout? – Tobias Schäfer Oct 31 '19 at 11:43
  • 1
    Don’t. Never block the JavaScript thread. Why do you want to pause script execution? – Dai Oct 31 '19 at 11:43
  • @Dai any other idea or solution to accomplish this? Thanks in advance – Devmix Oct 31 '19 at 11:43
  • I think this might be what you're looking for: https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep – hleskela Oct 31 '19 at 11:44
  • @Dai because inside the print function I actually have a ajax call and need to wait for it to finish executing and get a value from there, then assign the value to my str variable, so then finally return the value. – Devmix Oct 31 '19 at 11:45
  • 2
    Possible duplicate of [What is the JavaScript version of sleep()?](https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep) – Peter B Oct 31 '19 at 11:46
  • 2
    @progx if you have async operations to perform, then you can make use of Promises or simply callbacks – Sebastian Kaczmarek Oct 31 '19 at 11:47
  • 1
    @progx When working with ajax calls use their callbacks or wrap them in promises – empiric Oct 31 '19 at 11:47
  • 4
    @progx: you don't have to wait to get values, it's a terrible idea. Instead, learn how to [embrace asynchronicity](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call). – Wiktor Zychla Oct 31 '19 at 11:48
  • Can anyone provide an example please? I already looked into callbacks for 2 days but not getting this to work. Thanks – Devmix Oct 31 '19 at 11:48
  • 1
    Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Nick Parsons Oct 31 '19 at 11:50
  • @NickParsons they use callbacks. Basically a function that will collect your response (I get that), but how do you make myFunction return that response? Can you please provide a example/solution? Thanks a lot! – Devmix Oct 31 '19 at 11:56
  • @progx they also use other methods such as using a promise with `async/await`, here's an example: https://jsfiddle.net/L1mu2x76/1/ – Nick Parsons Oct 31 '19 at 12:13

3 Answers3

3

You can't delay the return of a function like you want, but you can return a Promise. For situations like that you need to use sime king of assynchronous function:

function myFunction() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve("I'm done");
    }, 5000)
  }
}

// Now when you use your function, you need to get the results from a then method:

let someVariable;

myFunction().then(function(output) {
  console.log(output); // I'm done
  someVariable = output;
}

console.log(someVariable); // undefined

Keep in mind that asynchronous functions will be always assynchronous. That's why the last console log will output undefined.

Elias Soares
  • 9,884
  • 4
  • 29
  • 59
  • But I need to make myFunction return "I'm done". Any ideas how to do that? – Devmix Oct 31 '19 at 12:08
  • 3
    You just can't. Can you exemplify your use case for your function? – Elias Soares Oct 31 '19 at 12:09
  • To delay the function like you want you will need to do a dump while, but this would crash your browser. – Elias Soares Oct 31 '19 at 12:09
  • Yes let me explain. I have this super Class that has a function called myFunction and I have this child class that extends the super class. Long story short I'm overriding the myFunction from my child class and I need to make this myFunction return a message (coming from an ajax call) and I need to make myFunction return that value. Does that make sense? – Devmix Oct 31 '19 at 12:17
  • Make sense, but's impossible to do what you want this way. You need to check who use the `myFunction` output and put all logic depending of it output inside some callback function (like the promise `.then() in my answer). – Elias Soares Oct 31 '19 at 14:18
  • Keep in mind that your function returns values immediately, while the ajax answer returns answers asynchronously. Everything after some async behavior must be async, even if you need to put a timeout to check for changes every second. – Elias Soares Oct 31 '19 at 14:20
  • I was able to get it to work. Thanks for your help. Marking it as the correct one! – Devmix Oct 31 '19 at 16:58
0

In the comments section i read that your using a AJAX and waiting for the response. So you can basically use the below.

function loadDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
     // DO THE REQUIRED HERE AFTER RESPONSE
    }
  };
  xhttp.open("GET", "ajax_info.txt", true);
  xhttp.send();
}
s_u_f
  • 200
  • 1
  • 12
0

You can use async function and WindowOrWorkerGlobalScope.setTimeout()

function sleep(seconds) {
  return new Promise(result => setTimeout(result, seconds * 1000))
}

async function myFunction() {
  // DO SOMEHITNG HERE so when it's done the finally return "I'm done"
  await sleep(4) // <-- 4 seconds
  return `I'm done`
}

async function asyncCall() {
  let str = ''
  console.log('str:', str) // <-- empty here

  str = await myFunction()
  console.log('str:', str) // <-- I\'m done
}

asyncCall()
Yosvel Quintero
  • 18,669
  • 5
  • 37
  • 46