134

I just want to get the return value from setTimeout but what I get is a whole text format of the function?

function x () {
    setTimeout(y = function () {
        return 'done';
    }, 1000);
    return y;
}

console.log(x());
8
  • your syntax is like that, it will return function only.
    – Mritunjay
    Commented Jul 24, 2014 at 8:36
  • do you want "done" to be returned? How can you return a result of function, which will be called 1000 ms later? Commented Jul 24, 2014 at 8:37
  • 1
    Timeouts are asynchronous, so you can't return from them. (well, you can, but the return value is going nowhere)
    – Ferdi265
    Commented Jul 24, 2014 at 8:37
  • better to get a callback in function x and call that function with done.
    – Mritunjay
    Commented Jul 24, 2014 at 8:38
  • 4
    const x = async (waitMs) => new Promise((resolve) => setTimeout(() => resolve('done'), waitMs)); console.log(await x(1000));
    – avalanche1
    Commented Apr 20, 2020 at 16:35

5 Answers 5

157

You need to use Promises for this. They are available in ES6 but can be polyfilled quite easily:

function x() {
   return new Promise((resolve, reject) => {
     setTimeout(() => {
       resolve('done!');
     });
   });
}

x().then((done) => {
  console.log(done); // --> 'done!'
});

With async/await in ES2017 it becomes nicer if inside an async function:

async function() {
  const result = await x();
  console.log(result); // --> 'done!';
}
4
  • actually the done in my example was a promise that needs to be returned inside a setTimeout..because i cant get the returned deferred.resolve() inside setTimeout. how would it be? thank you Commented Jul 24, 2014 at 9:33
  • 8
    Can you post a clearer example of your code in the question? Commented Jul 24, 2014 at 11:11
  • this is the best answer
    – Mariusz
    Commented Oct 28, 2022 at 22:02
  • It is better if you don't identify the argument passed to the function called by bind as done, some people may find it confusing as there is a string with bind above. x().then((promisedValue) => { console.log(promisedValue)}); // --> 'done!' Something like this.
    – gabs1bb3
    Commented Jun 10 at 13:11
18

You can't get a return value from the function you pass to setTimeout.

The function that called setTimeout (x in your example) will finish executing and return before the function you pass to setTimeout is even called.

Whatever you want to do with the value you get, you need to do it from the function you pass to setTimeout.

In your example, that would be written as:

function x () {
    setTimeout(function () {
        console.log("done");
    }, 1000);
}

x();
0
6

Better to take a callback for function x and whatever task you want to perform after that timeout send in that callback.

function x (callback) {
    setTimeout(function () {
        callback("done");
    }, 1000);
}

x(console.log.bind(console)); //this is special case of console.log
x(alert) 
1
  • 2
    Bare in mind, that this will not await after the function call, so it might actually not happen. For example add process.exit, after calling x and "done" will be never done.
    – user732456
    Commented Oct 30, 2018 at 8:42
-1

You can use a combination of Promise and setTimeOut like the example below

let f1 = function(){
    return new Promise(async function(res,err){
        let x=0;
        let p = new Promise(function(res,err){
            setTimeout(function(){
                x= 1;
                res(x);
            },2000)
        })
        p.then(function(x){
            console.log(x);
            res(x);
        })


    });
}
-6

I think you want have flag to know event occured or no. setTimeout not return a value. you can use a variable to detect event occured or no

var y="notdone";
   setTimeout(function () {
         y="done";
    }, 1000);

You can access variable y after timeout occured to know done or not

Not the answer you're looking for? Browse other questions tagged or ask your own question.