简体   繁体   English

jQuery .ajax()回调范围混淆

[英]jQuery .ajax() callback scope confusion

I am making requests in a loop, trying to accumulate the ID's of the objects given back each time and send to the subsequent request so that they do not get returned a second time. 我在循环中发出请求,尝试累积每次返回的对象的ID,并将其发送到后续请求,以使它们不再第二次返回。 However, the accumulator variable (obviously) is outside of .ajax() success callback, and is empty when I pass it through the data object of the call. 但是,累加器变量(显然)在.ajax()成功回调之外,当我将其通过调用的数据对象传递时为空。

function fill_div(id, count) {
    var rend = "";
    var filler = $('#'+id);
    for(i = 0; i < count; i++) {
        $.ajax({'type':'POST',
                'url':'/ads/render/',
                'dataType':'json',
                'data':"rendered="+rend}).success(function(data){
                    filler.append('<div id="' + data.adid + '"></div>');
                    rend+=data.mid.toString()+",";
                    _fill_ad(data);
                });
    }
}

When I look at the request in chrome's inspector, the variable is there in the post data, but there is no value. 当我在chrome的检查器中查看请求时,该变量位于发布数据中,但没有任何值。 I feel like I'm getting something messed up with scoping. 我觉得我在定义范围时遇到了麻烦。

It looks like the issue here is that you're expecting the returned values to be appended to the rend string in time for the next AJAX call. 看起来这里的问题是您期望返回的值会在下一次AJAX调用之前及时附加到rend字符串中。 This isn't going to happen, because making the calls is a synchronous process, but getting the return values is asynchronous. 这不会发生,因为进行调用是一个同步过程,但是获取返回值是异步的。 Instead of: 代替:

AJAX Post 1 (rend='')
rend += 'id1,'
AJAX Post 2 (rend='id1,')
rend += 'id2,'
AJAX Post 3 (rend='id1,id2,')
// etc

the sequence will most like go something like: 该序列最喜欢执行以下操作:

AJAX Post 1 (rend='')
AJAX Post 2 (rend='')
AJAX Post 3 (rend='')
// etc
// ... data is returned, not necessarily in order
rend += 'id2,'
rend += 'id1,'
rend += 'id3,'
// etc

In order to have each subsequent AJAX call aware of what's been previously returned from the server, you'd have to chain the calls, so that the next AJAX call isn't made until the previous call is completed. 为了使每个后续的AJAX调用了解先前从服务器返回的内容,您必须将调用链接起来,以便在上一个调用完成之前才进行下一个AJAX调用。 You could do this with recursion, like this: 您可以通过递归执行此操作,如下所示:

function fill_div(id, count) {
    var rend = "";
    var filler = $('#'+id);
    // inner function for recursion
    function doAjaxCall(i) {
        $.ajax({'type':'POST',
            'url':'/ads/render/',
            'dataType':'json',
            'data':{'rendered': rend})
            .success(function(data){
                filler.append('<div id="' + data.adid + '"></div>');
                rend+=data.mid.toString()+",";
                _fill_ad(data);
                // now send the next call
                if (i < count) {
                    doAjaxCall(i+1);
                }
            });
    }
    // kick off the series
    doAjaxCall(0);
}

Not sure it's the problem, but shouldn't it be like this for a POST ? 不知道这是问题所在,但对于POST来说不是这样吗?

function fill_div(id, count) {
    var rend = "";
    var filler = $('#'+id);
    for(i = 0; i < count; i++) {
        $.ajax({'type':'POST',
                'url':'/ads/render/',
                'dataType':'json',
                'data':{'rendered': rend})
                .success(function(data){
                    filler.append('<div id="' + data.adid + '"></div>');
                    rend+=data.mid.toString()+",";
                    _fill_ad(data);
                });
    }
}

(the difference is that the 'data' is an object and not a string) (不同之处在于“数据”是对象而不是字符串)

when the function fill_div executed, there is initialisation on 当执行函数fill_div时,将初始化

var rend = "";

and when the POST request constructed, 当构建POST请求时,

'data':"rendered="+rend

rend value will be empty 撕裂值将为空

Can you double check the variable name? 您可以仔细检查变量名称吗?

:) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM