我正在进行以下ajax调用:
def myfunction(var1, var2){
b1. $.ajax({
url: 'some_url2',
type: "POST",
data: {'mydata': var1, 'mydata2': var2},
success: function (data) {
b2. document.getElementById("successMessageAlert").style.display = "none";
},
error: function(xhr, errmsg, err) {
alert('error1 occurred');
b3. }
}
def function1() {
$.ajax({
url: 'some_url',
type: "POST",
data: formData,
success: function (data) {
var aData = JSON.parse(data);
b4. myfunction(getCookie('selected_Id'), aData);
b5. document.getElementById("successMessageAlert").style.display = "block";
b6. document.getElementById("successMessageText").innerHTML = "<strong>Success!</strong> The encoding record was saved successfully.";
}
},
error: function (xhr, errmsg, err) {
alert('error occurred')
}
});
}
我也在为csrf使用以下代码:
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
问题是myfunction
之后的语句是在myfunction
之前执行的。所以,&#34; successMessageAlert&#34;在再次隐藏之前短暂显示。
我使用了一些断点(b1-b6)。以下是他们的执行顺序:
基于阅读几个相关的SO帖子,我知道这个问题必须对ajax调用的异步性,beforesend
函数和回调做一些事情,但我无法将2和2放在一起。请帮忙。
PS:我需要更改帖子的标题。但我无法简洁地描述这个问题。
答案 0 :(得分:1)
尝试使用此async:false
ajax调用中的myfunction
$.ajax({
url: 'some_url2',
type: "POST",
async:false,
data: {'mydata': var1, 'mydata2': var2},
success: function (data) {
document.getElementById("successMessageAlert").style.display = "none";
},
error: function(xhr, errmsg, err) {
alert('error1 occurred');
}
如果有帮助,请标出答案
答案 1 :(得分:1)
实际上,执行流程绝对正确。我不认为它与beforeSend
有任何关系现在您需要了解JavaScript ajax调用的本质。 Ajax Call本质上是asynchronous
。
asynchronous
表示无论何时执行ajax调用,JavaScript都不会等待调用完成并转移到下一行代码。
例如在你的情况下
将b1
代码移至b3
后 - &gt;因为JavaScript不等待调用才能完成
现在问题是b2
何时会被执行。
这取决于网络流量,一旦ajax调用完成,b2
代码就会执行。
如何处理这些案例:
有两种方式
a)我不会建议这样做,即使用async:false
作为ajax调用中的参数。当在ajax调用中给出此参数时,它告诉JavaScript等待
b2
,不要继续b3
。
为什么我不建议这个
通话是同步的,如果您的请求需要3秒钟才能完成,那么您的网站将无响应3秒钟。
b)第二种方法使用回调:
这个有点复杂但是最好的方法。
首先,您需要确定依赖于ajax调用完成的代码,您可以将所有代码放在函数中,并在ajax调用完成后执行它
以下是示例:
def myfunction(var1, var2 , callback){
$.ajax({
url: 'some_url2',
type: "POST",
data: {'mydata': var1, 'mydata2': var2},
success: function (data) {
document.getElementById("successMessageAlert").style.display = "none";
callback(); //execute the passed function now
},
error: function(xhr, errmsg, err) {
alert('error1 occurred');
}
}
def function1() {
$.ajax({
url: 'some_url',
type: "POST",
data: formData,
success: function (data) {
var aData = JSON.parse(data);
myfunction(getCookie('selected_Id'), aData ,function(){
//Code will get executed after ajax call completes
document.getElementById("successMessageAlert").style.display = "block";
document.getElementById("successMessageText").innerHTML = "<strong>Success!</strong> The encoding record was saved successfully.";
});
}
},
error: function (xhr, errmsg, err) {
alert('error occurred')
}
});
}
答案 2 :(得分:1)
在jQuery中,ajax调用返回一个3对象进行异步处理。在其他功能中,它具有.done
函数,该函数在请求完成后附加回调以接收ajax结果。返回和使用此对象非常有用,因为它为各种继续处理打开了大门。
正如其他答案所述,迫使ajax调用同步行为并不是一个好主意,因为这会阻止所有其他处理,并可能导致非常糟糕的用户体验。
您应该在代码中使用它,以便仅在发生这种情况时操纵UI:
function myfunction(var1, var2){
// I guess the "successMessageAlert" should be here, no?
document.getElementById("successMessageAlert").style.display = "none";
return $.ajax({
url: 'some_url2',
type: "POST",
data: {'mydata': var1, 'mydata2': var2},
/* success: function (data) {
document.getElementById("successMessageAlert").style.display = "none";
},*/ // <- Bring this back if that's really what you wanted...
error: function(xhr, errmsg, err) {
alert('error1 occurred');
}
}
function function1() {
$.ajax({
url: 'some_url',
type: "POST",
data: formData,
success: function (data) {
var aData = JSON.parse(data);
myfunction(getCookie('selected_Id'), aData).done(function () {
document.getElementById("successMessageAlert").style.display = "block";
document.getElementById("successMessageText").innerHTML = "<strong>Success!</strong> The encoding record was saved successfully.";
});
},
error: function (xhr, errmsg, err) {
alert('error occurred')
}
});
}