我有下面的ajax代码,它工作正常:
$.ajax({
//async: false,
url: "/Tests/GetData/",
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function (data) {
$.each(data, function (i, item) {
$.ajax({
//async: false,
url: "/Tests/DoTask/",
type: 'POST',
data: { taskName: item.TaskName },
success: function () {
$("#Status").append('Task PASSED.<br/>');
},
error: function () {
$("#Status").append('Task FAILED!<br/>');
},
beforeSend: function () {
$("#Status").append('Doing task...<br/>');
}
});
});
$("#Status").append('Process completed.</span><br/>');
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
$("#Status").append('Error: ' + errorThrown + '<br/>');
},
beforeSend: function () {
$("#Status").append('<br/>Process started.<br/>');
}
});
这样做的问题是它是异步的,因此视图控件中的消息显示无序,所以我决定将选项 async:false 放入 ajax 中,但这会导致 Web 应用程序完全阻塞,尽管消息显示是有序的......坏主意,所以我想在实现一个队列来服务 ajax 调用而不使用选项 async:false。我用谷歌搜索,我找到了这个:
在上述页面的代码下方:
/* Class: Buffer
* methods: append
*
* Constructor: takes a function which will be the task handler to be called
*
* .append appends a task to the buffer. Buffer will only call a task when the
* previous task has finished
*/
var Buffer = function(handler) {
var tasks = [];
// empty resolved deferred object
var deferred = $.when();
// handle the next object
function handleNextTask() {
// if the current deferred task has resolved and there are more tasks
if (deferred.isResolved() && tasks.length > 0) {
// grab a task
var task = tasks.shift();
// set the deferred to be deferred returned from the handler
deferred = handler(task);
// if its not a deferred object then set it to be an empty deferred object
if (!(deferred && deferred.promise)) {
deferred = $.when();
}
// if we have tasks left then handle the next one when the current one
// is done.
if (tasks.length > 0) {
deferred.done(handleNextTask);
}
}
}
// appends a task.
this.append = function(task) {
// add to the array
tasks.push(task);
// handle the next task
handleNextTask();
};
};
看起来很有希望,所以我决定尝试一下,所以我修改了我的 ajax 代码并在结果下方,注意我已经替换了内部 ajax 块:
$.ajax({
//async: false,
url: "/Tests/GetData/",
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function (data) {
$.each(data, function (i, item) {
Buffer({
//async: false,
url: "/Tests/DoTask/",
type: 'POST',
data: { taskName: item.TaskName },
success: function () {
$("#Status").append('Task done.<br/>');
},
error: function () {
$("#Status").append('Task failed!<br/>');
},
beforeSend: function () {
$("#Status").append('Doing task...<br/>');
}
});
});
$("#Status").append('Process completed.</span><br/>');
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
$("#Status").append('Error: ' + errorThrown + '<br/>');
},
beforeSend: function () {
$("#Status").append('<br/>Process started.<br/>');
}
});
我不确定如果我正确使用了对缓冲区的调用,肯定不是因为我在控制器中的操作 DoTask 中放置了一个断点并且永不停止,所以我没有正确排队每个任务,对 Buffer 的调用似乎不正确...... . 所以我做错了什么?
第一次尝试(Paul Grime 的解决方案):我已经完成了您的解决方案,但我正在尝试修改一些我无法做到的事情:
1)我的 DoTask 返回一个 http 代码 200(如果任务完成)或 500(如果任务没有完成) HttpStatusCodeResult(HttpStatusCode.OK)/HttpStatusCodeResult(HttpStatusCode.NotFound) 所以在显示的字符串中(那个以 done 开头的字符串。 ..) 我想添加 doTask 的结果,例如:
如果 doTask 已经完成了任务:
“结果”:“通过”=> 完成 {“结果”:“通过”,...}
如果 doTask 没有正确完成任务:
“结果”:“失败”=> 完成 {“结果”:“失败”,...}
2)我已经对我的任务进行了分组,所以首先我启动执行一种任务,然后当这些任务完成后,无论它们是否正常,我都需要启动下一个要完成的任务,依此类推。 ..如何修改你的代码来做到这一点?
第二次尝试:
控制器:
[HttpPost]
public JsonResult GetData()
{
var data = (dynamic)null;
using (BBDDContext context = new BBDDContext())
{
data = context.MyObject.Where(o => o.TypeId == 1).OrderBy(k => k.Name).Select(obj => new
{
name =obj.Name,
description =obj.Description
}).ToList();
}
return Json(data, JsonRequestBehavior.AllowGet);
}
看法:
function getTasks() {
return ajax({
url: "/Tests/GetData/",
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8"
}).then(function (data) {
// data contains a list of pairs [Name IP]
return ok(createObject("status", "ok", "op", "getTasks", "data", JSON.stringify(data)));
}, function () {
return ok(createObject("status", "fail", "op", "getTasks"));
});
}
出于某种原因,当尝试打印“Received GetData results...”时,第一部分(“status”、“ok”、“op”、“getTasks”)被遗漏,只有最后一个与“data”相关的部分被打印(显示)。