0

我目前正在尝试解决 AJAX 的异步行为。问题是,我有未指定数量的 AJAX 调用,我都必须等待。我正在使用 jQuery 创建一个延迟对象,一旦最后一个 ajax 调用完成,包括其成功处理程序,该对象就会手动解析。工作正常,但是:似乎发生所有事情的函数在 then() 函数执行之前已经终止(并清除了在该函数中声明的所有变量)。我只能通过全局声明所需的变量用户来解决这个问题。

如果我声明

$().click(function() {
     /* inside here */ 
     var users = [];
});

然后它不起作用。控制台声明未声明 var users。(见代码示例)。

什么是解决此问题的干净方法?全局声明所有需要的变量对我来说似乎不是很好。

用我的代码示例链接到 jsfiddle

4

2 回答 2

1

您需要在所有函数都可以访问它的范围内声明该变量。由于您的getGroupMembers函数位于全局范围内,因此您的users变量必须如此。将其移动到readyorclick范围内,您可以将变量声明为本地变量。

但是,将请求的结果作为参数传递给resolve

$(document).ready(function() {
    $('#message_send').click(function() {
        var deferred = getGroupMembers({
            page: 1,
            per_page: 100
        });
        deferred.then(function(users) {
            console.log(users);
        });
    });
});

function getGroupMembers(querydata) {
    var users = [];
    var deferredObject = new $.Deferred();
    …
    // some asynchronous tasks, callbacking either
        deferredObject.resolve(users);
    // or
        deferredObject.reject();
    …
    return deferredObject.promise();
}

对于一些语法糖,您不妨只使用 Ajax Deferred 的pipe方法


递归管道方法:

function getGroupMembers(querydata) {
    return $.ajax({
        url: "/echo/json/",
        dataType: "json",
        data: querydata,
        cache: false
    }).pipe(function(data) {
        var user = data.response.UserActions,
            users = [];
        for (var u = 0; u < user.length; u++) {
            users.push(user[u].user.id);
        }
        if (querydata.page < data.meta.total_pages) {
            querydata.page++;
            return getGroupMembers(querydata).pipe(function(nextusers) {
                return users.concat(nextusers);
            });
        } else {
            return users;
        }
    });
}
于 2012-08-22T00:45:55.517 回答
0

你可以用闭包解决这个问题,但我建议看看 async.js

如果要将 ajax 调用的最后响应传递给下一个函数

https://github.com/caolan/async#series

如果您一个接一个地运行 ajax 可能是一个更好的选择是瀑布

https://github.com/caolan/async#waterfall

瀑布与系列相同,但如果任何功能失败/系列没有则停止

如果运行多个 ajax 调用并等待它们全部完成

https://github.com/caolan/async#parallel

于 2012-08-18T18:11:16.423 回答