简体   繁体   中英

Unexpected behavior with setTimeout

I have implemented an ajax polling function that I need to call continuously until the polling results come back with my expected results. In order to accomplish this, I am using setTimeout to introduce a delay so that the function doesn't just hammer the server with requests until it gets the results.

Let me preface this by saying that I have already found the way I need to implement the code to get the expected behavior I need. But, my question is in regards to the solution I found. I want to know why the solution worked with the timeout correctly, while the other one did not.

Here is the working code that successfully sets a timeout and polls for the result:

function makeRequest(url, data, requestType, successCallback, errorCallback, doneCallback) {
    $.ajax({
        url: url,
        type: requestType,
        data: data != null ? JSON.stringify(data) : '',
        contentType: 'application/json; charset=utf-8',
        success: function (success) {
            if (successCallback) successCallback(success);
        },
        error: function (error) {
            if (errorCallback) errorCallback(error);
        },
        done: function() {
            if (doneCallback) doneCallback();
        }
    });
}

function pollForResult(Id) {
    setTimeout(function () {
        makeRequest('/Transaction/TransactionResult/' + Id,
            null,
            "GET",
            function(result) {
                //success code here
            }, function(error) {
                //error callback implementation here
                if (error.status === 404) {
                    pollForResult(Id); //results not ready, poll again.
                } else {
                    alert("stopped polling due to error");
                }
            }, null);
    }, 2000);
}

Here is the code that doesn't properly set a timeout and just continually hits the server with requests:

function pollForResult(Id) {
    makeRequest('/Transaction/TransactionResult/' + Id,
        null,
        "GET",
        function(result) {
            //success code here
        }, function(error) {
            //error callback implementation here
            if (error.status === 404) {
                setTimeout(pollForResult(Id), 2000); //results not ready, poll again.
            } else {
                alert("stopped polling due to error");
            }
       }, null);
}

So, my question is this: what is it about the second block of code that makes it continually poll the server for results instead of waiting the 2 seconds to poll again?

I suspect, although I haven't tried, that this would work properly in the second block of code:

setTimeout(function(){ pollForResult(Id); }, 2000); //results not ready, poll again.
setTimeout(pollForResult(transactionId),2000);

This code immediately calls pollForResult and assigns its return value to be the function called when the timeout occurs.

This is desired behaviour, because you might have a function that builds a closure and passes that to the timeout. However it seems to catch out a lot of people...

As you said, function() {pollForResult(transactionId);} will work just fine.

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