AJAX GET请求递归加载文件

时间:2013-03-23 11:45:17

标签: jquery

我有以下情况。我想从服务器加载文件A(依赖于A的内容)将尝试加载文件A1,A2,A3,... An和每个文件A[1-n]将依次加载其他文件,这可以继续是的,它已经结束了。

不幸的是我已经意识到我需要使用synchronized $.ajax requests,否则第一个$ .ajax调用(当完成加载文件A时)只返回而不通过其余的文件。我的功能如下:

loadFile = function (path, file, scope)
{
    $.ajax ({
        url: url,
        type: 'GET',
        dataType: 'text',
        success: function (responseData)
        {
            var lines = responseData.split("\n");
            for (var j = 0; j < lines.length; j++)
            {
                if (lines[j].charAt(0) === 'F')
                    loadFile (arguments);
            }
        }
    });
}

我的第一个问题是为什么我不能在上面的选项中添加“async:false”,而是我必须使用$.ajaxSetup({async: false});,否则它不起作用。

我的第二个问题是这是用于递归执行此工作的正确模式。

我的第三个问题是我怎么知道整个过程何时完成。我无法弄清楚这一点。

1 个答案:

答案 0 :(得分:1)

async: false是万恶之源。它阻止了整个选项卡,在某些情况下(比较旧的IE)它会阻止整个浏览器。不要使用它。

现在解决您的问题。你可以这样做:

// note new argument "callback"
var loadFiles = function(path, file, scope, callback) {
    var req = $.ajax({
        // some settings
        success: function(res) {
            // some processing
            for (var j = 0; j < lines.length; j++) {
                loadFiles.requests.push(
                    // the same callback
                    loadFiles(path2, file2, scope2, callback)
                );
            }

            // set this request to complete
            req.completed = true;

            // check if all requests are done
            for (var i = 0; i < loadFiles.requests.length; i++) {
                if (!loadFiles.requests[i].completed) {
                    return;
                }
            }
            // TODO: you could remove completed requests from that array
            // to increase performance

            // if all are done then reset the array and run the callback
            delete loadFiles.requests;
            if (callback) {
                callback();
            }
        }
    });
    if (!loadFiles.requests || !loadFiles.requests.length) {
        loadFiles.requests = [req];
    }
    return req;
};

loadFiles(path, file, scope, function() {
    // this happens after all is done
});

请注意,连续两次调用此函数会破坏它(因为loadFiles.requests是全局函数的属性)。为了支持这一点,你必须将所有东西都包装在一个外部函数中并使用该函数。