我有一些代码可以在链中完成一组不同的操作。这组操作本身是在循环中执行的。由于我正在处理的系统的性质,操作集需要同步执行(即,在第一组完成之前,下一组操作不能执行)。异步执行可以抛弃远程处理器(不在我的控制之下),并导致代码失败。现在,我能够让这个工作的唯一方法是使用警报框,这是真正的跛脚,而不是一个选项。我试过了:
这是代码 - 任何想法?:
$('input:checked').each(function(index){
//get the item's location id
var currentInput = $(this).val();
var copyUser = function(){$.get(urlCopyPrefix + currentInput + urlSuffix);}
var moveUser = function(){$.get(urlMovePrefix + moveLocation + urlSuffix);}
var cleanup = function(){
var newSibling = $('#module-' + moveLocation);
newSibling.before('<li>New Line</li>');
alert('done');
}
/* --> THIS IS THE CODE IN QUESTION <-- */
$.when(copyUser()).pipe(moveUser).then(cleanup);
});
答案 0 :(得分:1)
我认为你必须停止使用.each()
,因为它会立即运行整个迭代而你不想这样做。
这是使用完成函数和本地函数执行此操作的一种方法:
function copyMove(moveLocation, urlCopyPrefix, urlMovePrefix, urlSuffix)
var checked = $('input:checked');
var index = 0;
function next() {
if (index < checked.length) {
var currentInput = checked.eq(index++).val();
$.get(urlCopyPrefix + currentInput + urlSuffix, function() {
$.get(urlMovePrefix + moveLocation + urlSuffix, function() {
$('#module-' + moveLocation).before('<li>New Line</li>');
next();
});
});
}
}
next();
}
或者,使用延迟:
function copyMove(moveLocation, urlCopyPrefix, urlMovePrefix, urlSuffix)
var checked = $('input:checked');
var index = 0;
function copyUser () {
var currentInput = checked.eq(index).val();
return $.get(urlCopyPrefix + currentInput + urlSuffix);
}
function moveUser() {
return $.get(urlMovePrefix + moveLocation + urlSuffix);
}
function cleanup() {
++index;
$('#module-' + moveLocation).before('<li>New Line</li>');
next();
}
function next() {
if (index < checked.length) {
$.when(copyUser()).pipe(moveUser).then(cleanup);
}
}
next();
}
关于延迟的说明:您必须传递函数引用,而不是函数调用。这意味着你传递函数名称没有parens。
答案 1 :(得分:1)
您必须从函数中返回jqXHR对象:
var copyUser = function(){
return $.get(urlCopyPrefix + currentInput + urlSuffix);
},
moveUser = function(){
return $.get(urlMovePrefix + moveLocation + urlSuffix);
};
然后你可以这样做:
$.when( copyUser() ).pipe( moveUser ).then( cleanup );
如果你想在下一个项目开始之前等待循环中的每个项目,请使用:
var $items = $('input:checked'),
length = $items.length,
copyUser = function(currentInput)
{
return $.get(urlCopyPrefix + currentInput + urlSuffix);
},
moveUser = function()
{
return $.get(urlMovePrefix + moveLocation + urlSuffix);
},
cleanup = function()
{
$('#module-' + moveLocation).before('<li>New Line</li>');
};
function processUser(i)
{
$.when( copyUser($items.eq(i).val()) ).pipe( moveUser ).then(function()
{
cleanup();
i < length && processUser(++i);
});
}
processUser(0);