注意:抱歉下面有伪代码的数量,但我不知道如何显示我正在尝试的内容。实际上有很多代码比我管理ajax图标和状态的解决方案中的代码要多得多,但是我把它愚蠢地显示出问题的根源。
基本上,我正在尝试在网页上创建一个流程循环,我发现它非常困难。我想要做的是显示交易清单。在页面顶部,我想向用户显示一个“全部处理”按钮,该按钮将一次处理一个事务。在服务器上处理事务时,用户应该能够取消进程循环。这只会停止发送 NEXT 交易;非常简单的取消。但是,由于ajax调用的异步性质,我正在苦苦挣扎。 :(
我在同步循环中工作得很好。但是,由于具有单线程特性,用户无法使用同步方法单击取消按钮。以下是我试图在异步循环中管理它的内容:
<a href="#" id="processAll">Process All</a>
<a href="#" id="cancelProcess">Cancel</a>
<table>
<tr><td><a href="#" id="processLink1">Process</a></td></tr>
<tr><td><a href="#" id="processLink2">Process</a></td></tr>
<tr><td><a href="#" id="processLink3">Process</a></td></tr>
<tr><td><a href="#" id="processLink4">Process</a></td></tr>
</table>
以下是处理上述链接的代码:
var currentId = null;
var isWaiting = false;
var userCancel = false;
$("#processAll").click(function(){
$(this).hide();
$("#cancelProcess").show();
userCancel = false;
// NOTE: this is where I think I need more logic...?
processNextTransaction();
});
$("#cancelProcess").click(function(){
$(this).hide();
$("#processAll").show();
userCancel = true;
});
$("a[id ^= processLink]").click(function(){
var id = $(this).attr("id").replace(/^processLink(/d+)$/, "$1");
doTransaction(id);
});
以下是我在上面三个代表中使用的辅助方法:
function processNextTransaction()
{
var anchorId = $("a[id ^= processLink]:first").attr("id");
var id = anchorId.replace(/^processLink(/d+)$/, "$1");
function check()
{
if (isWaiting)
setTimeout(check, 500);
else
{
if (!userCancel)
doTransaction(id);
}
}
check();
}
function doTransaction(id)
{
isWaiting = true;
currentId = id;
$.ajax({
type: "POST",
url: "/Transactions/Process/" + id,
data: {},
success: successHandler,
error: failHandler
});
}
function successHander(result)
{
// handle result...
$("#processLink" + currentId).replaceWith(result);
isWaiting = false;
}
function failHandler(result)
{
alert("Error: " + result);
$("#processLink" + currentId).replaceWith("Error!");
isWaiting = false;
}
请注意,我只调用processNextTransaction()
一次,这确实是我的主要问题。我考虑过从successHandler
和failHandler
开始,但这违背了setTimeout&amp;的目的。 isWaiting标志,当用户单击单个“进程”链接以处理单个事务时,还会导致其他问题。这是我第一次使用ajax循环场景体验...请帮忙! :)
在异步环境中管理进程列表的建议方法是什么?
答案 0 :(得分:3)
这应该有效:
<a href="#" id="processAll">Process All</a>
<a href="#" id="cancelProcess">Cancel</a>
<table>
<tr><td><a href="#" class="processLink" id="pl_1">Process</a></td></tr>
<tr><td><a href="#" class="processLink" id="pl_2">Process</a></td></tr>
<tr><td><a href="#" class="processLink" id="pl_3">Process</a></td></tr>
<tr><td><a href="#" class="processLink" id="pl_4">Process</a></td></tr>
</table>
jQuery魔术:
var cancel = false;
$('#processAll').click(function() {
process($('.processLink:first'), true);
cancel = false;
return false;
});
$('.processLink').click(function() {
process($(this), false);
return false;
});
$('#cancelProcess').click(function() {
cancel = true;
return false;
});
function process(el, auto) {
if(!cancel) {
var id = parseInt(el.attr('id').replace('pl_', '')); // Get numeric ID
$.ajax({
type: "POST",
url: "process.php?id=" + id,
success: function() {
el.html('Processed');
if(auto) { // If auto is true, process next ID
if($('#pl_'+(id + 1)).size() > 0) {
process($('#pl_'+(id + 1)), true);
}
}
}
});
}
}
如果在变量automatic
设置为true的情况下调用原始流程函数,则process函数使用success处理程序处理下一个元素。
如果已经开始,取消将不会取消该过程。显然。
您可能需要/需要不同类型的方法来遍历您的流程项,但我想这不是您的问题(这依赖于ID按数字升序排列)。
可在此处找到一个工作示例:http://www.ulmanen.fi/stuff/process.php
答案 1 :(得分:0)
您的代码太长,无法阅读,但根据您的介绍,我会做这样的事情:
创建排队机制(基本上是一个数组)。当用户想要处理某个事务时,将其添加到队列中,并调用一个类似doNextItemInQueue_unlessSomethingAlreadyRunning()
的函数。
该函数获取队列中的第一项(基本上是url),发出ajax请求,等待响应,然后再次调用自己。
如果要启用中止队列,请设置一个标志(例如abort_queue),并在doNextItemInQueue_unlessSomethingAlreadyRunning()
运行之前进行检查。