我刚刚花了三个小时调试一段代码,最后发现是因为我错误地假设以下代码执行的顺序是线性的:
$.ajax( {ajax options} );
console.log('I was assuming this would execute once the ajax request was complete');
这不是我第一次遇到这个问题了,我想知道这种行为的原因是什么?
是因为任何ajax请求都不会阻塞其他与ajax请求无关的脚本执行吗?
大多数其他答案都是回答如何处理这个问题。我想简单地探讨一下为什么在这种情况下异步操作是好的。
实际上,大多数浏览器中的JavaScript都是异步的。例如,看看这段代码:
document.getElementById('foo').onclick = function() {
alert('foo clicked');
};
document.getElementById('bar').onclick = function() {
alert('bar clicked');
};
哪个会先运行?你不知道,因为浏览器模型(或事实上大多数事件驱动代码)具有异步性。当发生事件时,您运行代码。您设置文档,然后等待事件发生,您的代码可能以各种不同的顺序执行,这取决于哪些事件首先发生。Javascript代码需要在页面的整个生命周期中执行,而不仅仅是在创建页面时。
所以,一般来说 Javascript编程(或者至少是超出最简单水平的Javascript编程)通常是异步的。此外,让HTTP请求异步化也是非常有意义的。
首先,正如您在问题中暗示的那样,使代码同步化将阻止执行。也就是说,您可能不希望由于两行代码之间进行了一个HTTP请求而使动画等待两秒钟才开始。服务器响应时间可能是(a)不规则的和(b)缓慢的,因此,将您的应用程序的设计依赖于服务器响应速度是没有意义的。
其次,更重要的是,您的用户不会因为您的脚本正在进行AJAX调用而停止使用页面。您的用户不关心。您的用户可能会关心,因为您的脚本目前正在处理不相关的AJAX请求,导致您的正常onscroll
行为不起作用。为配合整个浏览器Javascript编程的异步性质,绝大多数HTTP调用应该是非阻塞的、异步的。
ajax是异步的,如果你希望在ajax调用成功后执行某些操作,请使用success事件。
$.ajax({
url: 'yourserverpage.php',
success: function(data) {
alert('This will be executed only when ajax call is success /finished');
}
});
异步的意思是什么?
异步I/O或非阻塞I/O是一种输入/输出处理形式,允许传输完成之前其他处理继续进行。异步I/O用于提高吞吐量、延迟和/或响应能力。
jQuery $.ajax()
提供了4个(事件)选项:beforeSend、success、error和complete。在您的情况下,我认为complete是正确的答案。
例如:
$.ajax({
url: someUrl,
//...
beforeSend: function(){
console.log("I'm sending AJAX.");
//display loading?
},
success: function(data){
console.log('response: '+data);
},
error: function(er){
console.log(er.responseText);
},
complete: function(){
console.log("I'm done.");
//hide loading?
}
});
success:
函数中,如下所示:$.ajax({
url: 'ajax/test.html',
success: function(data) {
// Do something after AJAX is completed.
console.log('I was assuming this would execute once the ajax request was complete');
}
});
你可以成功完成,或者也可以使用 .done();
$.ajax( {ajax options} ).done(console.log('I was assuming this would execute once the ajax request was complete'));
另一个选项是将async设置为false
$.ajax({
async : 'false',
other options
});
通过这种方式,直到$.ajax语句执行完成之前,您的下一条语句将不会被执行。
$.ajax
是一个异步函数,因此在返回之前不会等待请求完成。相反,当请求结束时,它会调用您通过 success
和/或 error
指定的回调函数。
如果您确实需要同步行为,可以将选项 async
设置为 false(请参见 docu)。但是,在这种情况下,请注意,整个 UI 将冻结,直到请求完成!
正如其他人所说,ajax代表异步JavaScript和XML。 话虽如此,您可以使用{{link1:jquerys ajax}}函数执行以下任一操作:
如果要使调用同步,则将“async”选项设置为false。 默认情况下为true。 请参阅文档。 自jQuery 1.8以来,不建议使用此属性。
提供“complete”回调。 默认情况下,这将异步发生。 这是:
请求完成后(在成功和错误回调之后)要调用的函数。
提供“success”回调。 默认情况下,这将异步发生。 这是:
如果请求成功,则要调用的函数。
AJAX中的第一个A代表异步;这意味着AJAX调用在后台执行,不会阻塞脚本的执行直到它们完成。这基本上是按设计来实现的。
如果你想在调用完成时运行一些代码,可以在以下一个或多个参数中传递一个函数:
$.ajax({
// your other options
done: function(data, textStatus, jqXHR) {
alert('Success! I got the following data back: ' + data);
// this runs when the request has finished successfully
},
fail: function(jqXHR, textStatus, errorThrown) {
alert('Oops, there was an error :(');
// this runs when the request has finished, but with an error
},
always: function(jqXHR, textStatus) {
alert("OK, I'm done.");
// this runs when the call is finished, regardless
// of whether it has succeeded or not
}
更多信息,请查看API:http://api.jquery.com/jQuery.ajax
async:true
。同步请求可能会暂时锁定浏览器,禁止任何操作,直到请求结束。不建议使用。 - jasssonpet