Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用jQuery和AJAX的JS变量的生存期_Javascript_Variables_Deferred_Lifetime - Fatal编程技术网

Javascript 使用jQuery和AJAX的JS变量的生存期

Javascript 使用jQuery和AJAX的JS变量的生存期,javascript,variables,deferred,lifetime,Javascript,Variables,Deferred,Lifetime,我目前正在尝试绕过AJAX的异步行为。问题是,我有大量的AJAX调用需要等待。我正在使用jQuery创建一个延迟对象,在最后一次ajax调用完成后,包括成功处理程序后,该对象将立即手动解析。工作正常,但是:似乎在then()函数执行之前,发生所有事情的函数已经终止(并清除了该函数中声明的所有变量)。我只能通过全局声明所需的变量用户来解决这个问题 如果我申报 $().click(function() { /* inside here */ var users = []; })

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

如果我申报

$().click(function() {
     /* inside here */ 
     var users = [];
});
那就不行了。控制台声明未声明var用户。(参见代码示例)

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


您可以通过闭包解决这个问题,但我建议您看看async.js

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

https://github.com/caolan/async#series
如果您正在一个接一个地运行ajax,那么最好的选择可能是瀑布

瀑布与series相同,但如果任何函数失败/series没有失败,则会停止

在运行多个ajax调用并等待它们全部完成的情况下


您需要在所有函数都可以访问的范围内声明变量。由于您的
getGroupMembers
函数在全局范围内,因此您的
users
变量需要在全局范围内。将其移动到
就绪
单击
范围,您可以将变量声明为本地变量

但是,将请求的结果作为参数传递给
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的


递归管道方法:

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;
        }
    });
}
函数getGroupMembers(querydata){ 返回$.ajax({ url:“/echo/json/”, 数据类型:“json”, 数据:querydata, 缓存:false }).管道(功能(数据){ var user=data.response.UserActions, 用户=[]; 对于(var u=0;u如果您希望一个变量是全局可用的,那么您可能应该全局定义它——或者至少,将它放在代码其余部分都知道要检查的地方。问题是,这个变量不需要全局可用。它是在一个函数中声明的,所有其他调用都是从该函数中进行的。我猜这个函数在真正结束之前就“结束了”。由这些异步ajax调用和延迟对象引起,即使函数本身已经结束,它们仍然会运行。为什么不将用户作为参数传递?您的问题是:“如何等待N个ajax调用完成?”还是“我将从多个异步ajax调用(全局变量除外)中累积的状态存储在哪里?”在等待最后一个ajax调用完成时?“好问题:)我会说:问题是,“即使内部的操作仍然有效,父函数真的已经终止了吗?”