ajax 每个循环中的调用均未按预期运行
ajax call in each loop functions as not expected
我有一个函数可以输出一个名为 DisplayComments(comments)
的数组。在此函数中,我进行了 ajax 调用以检索与 comments
关联的 replies
。
当ajax为运行取回replies
,从webapicontroller返回数组后,代码跳出ajax然后转到 each loop
的最后一行,即 $('#div_ListOfComments').append(replies);
。然后它返回到循环的第一行,即 var cid = comment.CommentId;
并继续下一个注释项。然后,ajax 调用发生在第二个 comment
上,它的行为方式相同。在所有 comments
的 each loop
完成之前,它永远不会访问 ajax 调用的 Success
状态。然后,它移动到成功部分并为每个 reply
项目运行一次代码以将它们显示在表单上。
但是,我需要在每个评论下面附加 replies
,换句话说,我需要在 comment
之后将 replies
附加到 $('#div_ListOfComments')
附加。但是,下面说明的代码未按预期方式运行。它附加所有评论。然后附加回复。谁能看出下面的代码有什么问题吗?
function LoadCommentsForPost(postid) {
jQuery.support.cors = true;
$.ajax({
url: '/api/Comment/GetCommentsByPost?pid=' + postid,
type: 'GET',
contentType: "application/json; charset=utf-8;",
dataType: 'json',
success: function (response) {
},
error: function (x, y, z) {
alert(x + '\n' + y + '\n' + z);
},
complete: function (jqXHR, textStatus) {
var comments = JSON.parse(jqXHR.responseText);
comments = comments["$values"];
DisplayComments(comments);
}
});
}
function DisplayComments(comments) {
$('#div_ListOfComments').html('');
$.each(comments, function (index, comment) {
//the current comment is appended to $('#div_ListOfComments')
var cid = comment.CommentId;
var replies;
$.ajax({
url: '/api/Reply/GetRepliesByComment?cid=' + cid,
type: 'GET',
contentType: "application/json; charset=utf-8;",
dataType: 'json',
success: function (response) {
//VS break-point works just before here
//and I see a valid return value from VS
//the program continue to work outside of the ajax
//with this line below: $('#div_ListOfComments').append.....
},
error: function (x, y, z) {
alert(x + '\n' + y + '\n' + z);
}
});
$('#div_ListOfComments').append(replies);
});
}
Ajax 是异步的。对 $.ajax()
的调用只会启动 ajax 调用。然后是执行后的代码行。在服务器 returns 响应 ajax 调用之后,才会调用 success
回调。
您也不能指望 ajax 回复会按照您提出请求的顺序返回。
你可以这样做:
function DisplayComments(comments) {
$('#div_ListOfComments').html('');
$.each(comments, function (index, comment) {
var cid = comment.CommentId;
// Append the comment to $('#div_ListOfComments').
// Append an empty div to $('#div_ListOfComments') that will hold the replies,
// giving it an id based on cid.
$.ajax({
url: '/api/Reply/GetRepliesByComment?cid=' + cid,
type: 'GET',
contentType: "application/json; charset=utf-8;",
dataType: 'json',
success: function (response) {
// Put the replies in the div with the id based on cid.
// cid will have the correct value because this is a closure.
}
});
});
}
另一种方法是将评论和回复保留在数据中,直到最后一次 ajax 调用 returns,然后将它们全部添加到页面。
function DisplayComments(comments) {
var replies = {};
var deferreds = $.map(comments, function(comment) {
var cid = comment.CommentId;
return $.ajax({
url: '/api/Reply/GetRepliesByComment?cid=' + cid,
type: 'GET',
contentType: "application/json; charset=utf-8;",
dataType: 'json',
success: function(reply) {
replies[cid] = reply;
}
});
});
// This executes the function when all the ajax calls have returned.
$.when.apply($, deferreds).then(function() {
$('#div_ListOfComments').html('');
$.each(comments, function(i, comment) {
var reply = replies[comment.id];
$('#div_ListOfComments').append(comment.text).append(reply);
});
});
}
。
此外,我建议您更改级联 ajax 调用的使用。您可以使用 deferred/promise 方法。
您的代码将如下所示
function LoadCommentsForPost(){
jQuery.support.cors = true;
return $.ajax({
url: '/api/Comment/GetCommentsByPost?pid=' + postid,
type: 'GET',
contentType: "application/json; charset=utf-8;",
dataType: 'json'
});
}
function LoadCommentsForPostError(x, y, z) {
alert(x + '\n' + y + '\n' + z);
}
function RetrievedComments(jqXHR, textStatus)
{
var comments = JSON.parse(jqXHR.responseText);
comments = comments["$values"];
DisplayComments(comments);
}
function DisplayComments(comments) {
$('#div_ListOfComments').html('');
$.each(comments, function (index, comment) {
var cid = comment.CommentId;
// Append the comment to $('#div_ListOfComments').
// Append an empty div to $('#div_ListOfComments') that will hold the replies,
// giving it an id based on cid.
$.ajax({
url: '/api/Reply/GetRepliesByComment?cid=' + cid,
type: 'GET',
contentType: "application/json; charset=utf-8;",
dataType: 'json',
success: function (response) {
// Put the replies in the div with the id based on cid.
// cid will have the correct value because this is a closure.
}
});
});
}
$.when(LoadCommentsForPost()).then(RetrievedComments, LoadCommentsForPostError);
更多信息在 $.when documentation
我有一个函数可以输出一个名为 DisplayComments(comments)
的数组。在此函数中,我进行了 ajax 调用以检索与 comments
关联的 replies
。
当ajax为运行取回replies
,从webapicontroller返回数组后,代码跳出ajax然后转到 each loop
的最后一行,即 $('#div_ListOfComments').append(replies);
。然后它返回到循环的第一行,即 var cid = comment.CommentId;
并继续下一个注释项。然后,ajax 调用发生在第二个 comment
上,它的行为方式相同。在所有 comments
的 each loop
完成之前,它永远不会访问 ajax 调用的 Success
状态。然后,它移动到成功部分并为每个 reply
项目运行一次代码以将它们显示在表单上。
但是,我需要在每个评论下面附加 replies
,换句话说,我需要在 comment
之后将 replies
附加到 $('#div_ListOfComments')
附加。但是,下面说明的代码未按预期方式运行。它附加所有评论。然后附加回复。谁能看出下面的代码有什么问题吗?
function LoadCommentsForPost(postid) {
jQuery.support.cors = true;
$.ajax({
url: '/api/Comment/GetCommentsByPost?pid=' + postid,
type: 'GET',
contentType: "application/json; charset=utf-8;",
dataType: 'json',
success: function (response) {
},
error: function (x, y, z) {
alert(x + '\n' + y + '\n' + z);
},
complete: function (jqXHR, textStatus) {
var comments = JSON.parse(jqXHR.responseText);
comments = comments["$values"];
DisplayComments(comments);
}
});
}
function DisplayComments(comments) {
$('#div_ListOfComments').html('');
$.each(comments, function (index, comment) {
//the current comment is appended to $('#div_ListOfComments')
var cid = comment.CommentId;
var replies;
$.ajax({
url: '/api/Reply/GetRepliesByComment?cid=' + cid,
type: 'GET',
contentType: "application/json; charset=utf-8;",
dataType: 'json',
success: function (response) {
//VS break-point works just before here
//and I see a valid return value from VS
//the program continue to work outside of the ajax
//with this line below: $('#div_ListOfComments').append.....
},
error: function (x, y, z) {
alert(x + '\n' + y + '\n' + z);
}
});
$('#div_ListOfComments').append(replies);
});
}
Ajax 是异步的。对 $.ajax()
的调用只会启动 ajax 调用。然后是执行后的代码行。在服务器 returns 响应 ajax 调用之后,才会调用 success
回调。
您也不能指望 ajax 回复会按照您提出请求的顺序返回。
你可以这样做:
function DisplayComments(comments) {
$('#div_ListOfComments').html('');
$.each(comments, function (index, comment) {
var cid = comment.CommentId;
// Append the comment to $('#div_ListOfComments').
// Append an empty div to $('#div_ListOfComments') that will hold the replies,
// giving it an id based on cid.
$.ajax({
url: '/api/Reply/GetRepliesByComment?cid=' + cid,
type: 'GET',
contentType: "application/json; charset=utf-8;",
dataType: 'json',
success: function (response) {
// Put the replies in the div with the id based on cid.
// cid will have the correct value because this is a closure.
}
});
});
}
另一种方法是将评论和回复保留在数据中,直到最后一次 ajax 调用 returns,然后将它们全部添加到页面。
function DisplayComments(comments) {
var replies = {};
var deferreds = $.map(comments, function(comment) {
var cid = comment.CommentId;
return $.ajax({
url: '/api/Reply/GetRepliesByComment?cid=' + cid,
type: 'GET',
contentType: "application/json; charset=utf-8;",
dataType: 'json',
success: function(reply) {
replies[cid] = reply;
}
});
});
// This executes the function when all the ajax calls have returned.
$.when.apply($, deferreds).then(function() {
$('#div_ListOfComments').html('');
$.each(comments, function(i, comment) {
var reply = replies[comment.id];
$('#div_ListOfComments').append(comment.text).append(reply);
});
});
}
您的代码将如下所示
function LoadCommentsForPost(){
jQuery.support.cors = true;
return $.ajax({
url: '/api/Comment/GetCommentsByPost?pid=' + postid,
type: 'GET',
contentType: "application/json; charset=utf-8;",
dataType: 'json'
});
}
function LoadCommentsForPostError(x, y, z) {
alert(x + '\n' + y + '\n' + z);
}
function RetrievedComments(jqXHR, textStatus)
{
var comments = JSON.parse(jqXHR.responseText);
comments = comments["$values"];
DisplayComments(comments);
}
function DisplayComments(comments) {
$('#div_ListOfComments').html('');
$.each(comments, function (index, comment) {
var cid = comment.CommentId;
// Append the comment to $('#div_ListOfComments').
// Append an empty div to $('#div_ListOfComments') that will hold the replies,
// giving it an id based on cid.
$.ajax({
url: '/api/Reply/GetRepliesByComment?cid=' + cid,
type: 'GET',
contentType: "application/json; charset=utf-8;",
dataType: 'json',
success: function (response) {
// Put the replies in the div with the id based on cid.
// cid will have the correct value because this is a closure.
}
});
});
}
$.when(LoadCommentsForPost()).then(RetrievedComments, LoadCommentsForPostError);
更多信息在 $.when documentation