Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return variable after setTimeout

I'm trying to return a variable only after it has been set within a setTimeout callback. I couldn't think of any other way to do this, but here's my attempt (I know the code seems silly, but it's to work around a Cordova bug). For reasons beyond my understanding, it results in an infinite loop.

function isConnected() {
    var done = false;
    setTimeout(function() {
        done = true;
    }, 500);

    while (!done) {}
    return navigator.connection.type!== Connection.NONE;
}

Can anyone explain to me why this is happening, or provide an alternative?

Update (solution):

function isConnected(callback) {
    setTimeout(function() {     
        callback(navigator.connection.type !== Connection.NONE);
    }, 500);
}


isConnected(function(connected) {
    if (!connected)
        alert('Not Connected');
});
like image 327
Drazen Bjelovuk Avatar asked Nov 14 '13 19:11

Drazen Bjelovuk


People also ask

How do I return a variable from setTimeout?

To get return value from setTimeout with JavaScript, we can create a promise from the setTimeout code. const x = () => { const promise = new Promise((resolve, reject) => { window. setTimeout(() => { resolve("done!"); }); }); return promise; }; const y = async () => { const result = await x(); console. log(result); };

Can we return something from setTimeout?

Return valueThe returned timeoutID is a positive integer value which identifies the timer created by the call to setTimeout() . This value can be passed to clearTimeout() to cancel the timeout.

What type does setTimeout return?

This approach is needed, because the return type of the setTimeout method is NodeJS. Timeout in Node and number in the browser.

Does setTimeout execute immediately?

Next, you can pass the milliseconds parameter, which will be the amount of time JavaScript will wait before executing the code. If you omit the second parameter, then setTimeout() will immediately execute the passed function without waiting at all.


1 Answers

You simply can't solve your problem that way. Because javascript is single threaded, the setTimeout callback can only run when your JS thread of execution finishes so with your infinite loop, it will never get to run and your code will hang. Eventually the browser will complain about a long-running piece of JS and offer to shut it down.

Instead, you need to use a callback function on the setTimeout() and continue your code from that callback. You can't use sequential code for timeouts. You must use asynchronous coding styles.

You could do something like this where you pass in a callback and it calls the callback back and passes it the connected boolean:

function GetConnectedState(callback) {

    setTimeout(function() {     
        callback(navigator.connection.type !== Connection.NONE);
    }, 500);

}

Your existing code doesn't seem to offer anything other than a look at the connection state in 1/2 second. With any real sort of asynchronous operation in javascript (such as an ajax call or a websocket connection), there should also be a success or completion callback that will tell you when/if the operation actually completes and you can also trigger the callback based on that (sooner than 1/2 second most of the time). So, this doesn't really look like a complete solution, but it's all you show us you're using.

For example, here's an answer you can look at that calls a callback when an images loads successfully, with an error or times out with no response: Javascript Image Url Verify and How to implement a "function timeout" in Javascript - not just the 'setTimeout'. A similar concept could be used for implementing your own timeout on some other type of asynchronous call.

like image 52
jfriend00 Avatar answered Oct 18 '22 07:10

jfriend00