setTimeout出现意外行为

时间:2014-02-19 15:32:59

标签: javascript jquery settimeout

我已经实现了一个ajax轮询功能,我需要不断调用,直到轮询结果返回我的预期结果。为了实现这一点,我使用setTimeout来引入一个延迟,这样函数就不会在服务器上发出请求,直到获得结果为止。

让我先说一下,我已经找到了实现代码所需的方法来获得我需要的预期行为。但是,我的问题是关于我找到的解决方案。我想知道为什么解决方案正确处理超时,而另一个没有。

以下是成功设置超时并轮询结果的工作代码:

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

以下代码没有正确设置超时,只是不断地通过请求命中服务器:

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

所以,我的问题是:第二块代码是什么让它不断轮询服务器的结果,而不是等待2秒再次轮询?

我怀疑,虽然我没有尝试,但这可以在第二段代码中正常工作:

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

1 个答案:

答案 0 :(得分:3)

setTimeout(pollForResult(transactionId),2000);

此代码立即调用pollForResult并将其返回值指定为超时发生时调用的函数。

这是所需的行为,因为您可能有一个构建闭包并将其传递给超时的函数。然而它似乎赶上了很多人......

如你所说,function() {pollForResult(transactionId);}可以正常使用。