最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Return variable after setTimeout - Stack Overflow

programmeradmin1浏览0评论

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');
});

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');
});
Share Improve this question edited Oct 9, 2017 at 7:22 Drazen Bjelovuk asked Nov 14, 2013 at 19:20 Drazen BjelovukDrazen Bjelovuk 5,4725 gold badges43 silver badges67 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 8

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.

As I revisit this 5 years later, can't help but to offer up a fancier alternative:

await new Promise(function(resolve) {
  setTimeout(resolve, 500);
});
if (navigator.connection.type === Connection.NONE) {
  alert('Not Connected');
}

Javascript is single-threaded. The timeout function can't run until your script returns to the main event loop. But as long as you're in the while loop it will never return, so the timeout function never runs, so done is never set to true.

It's not possible in Javascript to wait for an asynchronous event before returning.

发布评论

评论列表(0)

  1. 暂无评论