简体   繁体   English

JavaScript while循环回调

[英]Javascript while loop callback

function jQueryFunction(url,callback)
{ 
    $.ajax
    ({
        type: "GET",
        async: false,
        url: url,
        dataType: "jsonp",
        jsonp: "callback",
        jsonpCallback: "tpsHandler",
        success: function(json)
        {
            return callback(json);
        }
    });  
}

function tmpFunction(callback) 
{
    var jsonArray = new Array();
    var i = 0;

    while(true)
    {
        for(var j = 0; j < url_array.length; j++)
        {
            jQueryFunction(url_array[j], function(json){
                jsonArray[j] = json;
                i++;
            });
        }

        if(i >= url_array.length)
        {
            return callback(jsonArray);
        }
        else
        {
            alert(i);
        }
    }
}

When I call tmpFunction the website keeps displaying "0" to me. 当我调用tmpFunction时,网站一直向我显示“ 0”。 Why is i always 0? 为什么i总是0? Does tmpFunction never run the for loop? tmpFunction永远不会运行for循环吗?

From the jQuery documentation : jQuery文档中

By default, all requests are sent asynchronously (ie this is set to true by default). 默认情况下,所有请求都是异步发送的(即默认情况下设置为true)。 If you need synchronous requests, set this option to false. 如果需要同步请求,请将此选项设置为false。 Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. 跨域请求和dataType:“ jsonp”请求不支持同步操作。 Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active. 请注意,同步请求可能会暂时锁定浏览器,从而在请求处于活动状态时禁用任何操作。 As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; 从jQuery 1.8开始,不建议使用async:false和jqXHR($ .Deferred); you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done() or the deprecated jqXHR.success(). 您必须使用成功/错误/完成回调选项,而不要使用jqXHR对象的相应方法,例如jqXHR.done()或已弃用的jqXHR.success()。

As shown above, you can't use jsonp with synchronous requests. 如上所示,您不能将jsonp与同步请求一起使用。 So yes, your success callback is not getting executed (not even sure whether jQuery would trigger a callback if a function is synchronous in lieu of just return the value). 因此,是的,您的成功回调未得到执行(甚至不确定如果函数是同步的而不是仅返回值,jQuery是否会触发回调)。

Furthermore, I suggest that you never make synchronous AJAX requests since network requests are long-running operations that can destroy user experience. 此外,我建议您不要进行同步AJAX请求,因为网络请求是长期运行的操作,可能会破坏用户体验。 Instead, take @Altinak 's advice and use Deferred objects. 相反,请采用@Altinak的建议并使用Deferred对象。

Place the i after the jQueryFunction call. 将i放在jQueryFunction调用之后。

Don't forget to place a "break;" 不要忘记放置一个“中断”; after alert(i) to get out of the while loop. 在alert(i)之后退出while循环。

If the i must be inside the callback in jQueryFunction call use a done to place your code to execute after ajax, and don't use i. 如果i必须在jQueryFunction调用的回调中,请使用done将代码放置在ajax之后执行,并且不要使用i。 Change async to true in the ajax call to get done to work. 在ajax调用中将async更改为true以完成工作。

$.ajax( //your settings
).done(function(data){
    //check the value in data instead of i.
    //due to .ajax being asynchronous code that needs to wait needs
    //to be in .done or the success callback.
});

A better solution to this entire problem is to use deferred objects. 解决整个问题的更好方法是使用延迟对象。

I'm going to ignore the while (true) bit for now, since that doesn't make sense: 现在,我将忽略while (true)位,因为这没有任何意义:

function jQueryFunction(url)
{ 
    return $.ajax({
        type: "GET",
        async: true,                  // NB: **not** false
        url: url,
        dataType: "jsonp",
        jsonp: "callback",
        jsonpCallback: "tpsHandler"   // any good reason why you're defining this?
    });  
}

function tmpFunction(callback) 
{
    var def = [];     

    for (var i = 0; i < url_array.length; ++i) {
        def.push(jQueryFunction(url_array[i]));
    }

    return $.when.apply($, def).done(callback);
}

This will run all of the AJAX queries in parallel (subject to per-host client connection limits) and once they're all done, callback will be invoked with each of the results (in submission order) in the arguments array. 这将并行运行所有AJAX查询(受每个主机客户端连接的限制),一旦完成,将在arguments数组中以每个结果(提交顺序)调用callback

NB: this isn't quite the same as your original semantics which has callback passed a single parameter that is the array of results. 注意:这与您的原始语义不太一样,后者的callback传递了一个参数,即结果数组。 If you want to keep that, use: 如果要保留,请使用:

.done(function() {
    var args = [].slice.call(arguments, 0);
    callback.call(this, args);
});

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

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