递归函数和 setTimeout 与 setInterval

Recursive function and setTimeout vs setInterval

请考虑以下事项:

$(document).ready(function () {
    var promise;

    (function refresh(){
        promise = loadInfo();
        promise.done( function() {
            $.each(loadedData, function(key, value){
                $('#' + key + ' div.info').html(value.label);
            })
            // Call itself for next iteration
            window.setTimeout(refresh, 5 *1000);
        })
    })()
})

谢谢

由于 promise 变量是在刷新函数之上声明的,因此它可以通过闭包使用并将被重新使用,因此不会导致堆栈溢出,但 loadInfo 的实现将确定是否创建新变量每次与否。

这可能有助于阐明 JavaScript 和变量范围:How do JavaScript closures work?

也许稍微清理过的版本看起来像这样:

$(document).ready(function () {
    (function refresh(){
        loadInfo().done( function(loadedData) {
            $.each(loadedData, function(key, value){
                $('#' + key + ' div.info').html(value.label);
            });
            // Call itself for next iteration
            window.setTimeout(refresh, 5 *1000);
        });
    })();
});

对于某些人来说,使用 setInterval 可能更具可读性,但我认为您的 setTimeout 方法很好。

当前代码中的setTimeout会等待函数完成,然后等待指定的时间,然后调用刷新函数。

setInterval 将在给定的时间后继续调用该函数,无论该函数是否已完成执行

setInterval 确保定期请求(但不确保响应顺序)但 setTimeout(您的代码)不能确保这一点。如果响应时间长,则等待时间也顺延。另外,如果您的 loadInfo() 请求失败,下一个请求需要更多代码。

决定取决于您的服务器环境和您应用的优先级。(在性能和准确性之间)

如果有帮助,请参考我的 setTimeout 代码。

$(document).ready(function () {

    // for api
    function repeatLoad( cb ) {

        var bindedRepeatLoad = repeatLoad.bind( this, cb );
        var repeat = setTimeout.bind( this, bindedRepeatLoad, 5*1000 );

        loadInfo()
        .done( cb )
        .done( repeat )
        .error( repeat );
    }

    // for view
    function render( loadedData ) {
        $.each(loadedData, function(key, value){
            $('#' + key + ' div.info').html(value.label);
        });
    }

    // for app logic, only 1 line is needed.
    repeatLoad( render );
});