简体   繁体   中英

How do I use setTimeout with recursion to wait for a variable to be defined in JavaScript?

I want to wait until storage.get('session')!=null , then execute the callback .

The problem I'm having is that my recursive setTimeout method is running exponentially instead of checking if the variable is defined every second.

The result is waitForElement being executed thousands of times per second which I do not want.. I want it to execute once every 1 second until storage.get('session')!=null

waitForElement(function(){
    console.log("DONE!");
});

function waitForElement(callback){
    if(storage.get('session')!=null)
    {
        console.log("session exists now");
        if(typeof callback=="function")
        {
            callback();
        }
    }
    else
    {
        console.log("session still does not exist. Checking again in 1 second");

        //ISSUE: THIS RUNS IMMEDIATELY AND FOREVER!
        setTimeout(waitForElement(function(cb){
                if(typeof cb == "function"){
                    cb();
                }
        }), 1000);
    }
}

You shouldn't be using timeouts at all - Promises are the preferred model for this sort of asynchronous handling these days, eg

function login() {
    return new Promise((resolve, reject) => {
        // do something that creates the session
        if (successful) {
            resolve();
        } else {
            reject();
        }
    })
}

// promise that will eventually be resolve when the user logs in
var loggedIn = login();

// multiple (potentially parallel) actions
loggedIn.then(doSomething);
loggedIn.then(doSomethingElse);

// serial actions
loggedIn.then(doFirstThing).then(doSecondThing);

It's because you're immediately invoking the function waitForElement when you set your timeout. Try this

var callback = function(cb){
    if(typeof cb == "function"){
        cb();
    }
}

setTimeout(waitForElement.bind(this, callback), 1000);

You are immediately calling waitForElement. You need to pass a function reference which is basically a function name without the "()". Given that your function doesn't have "this" there no need to worry about context for this case.

setTimeout(function() {
    waitForElement(function(cb){
        if(typeof cb == "function"){
            cb();
        }
    });
}, 1000);

Also something to note is that you never pass anything into the callback function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM