1

我有一些代码可以在链中完成一组不同的操作。这组操作本身是在循环中执行的。由于我正在处理的系统的性质,操作集需要同步执行(即下一组操作在第一组完成之前无法执行)。异步执行会抛出远程处理器(不在我的控制范围内),并导致代码失败。现在,我能够让它工作的唯一方法是使用警报框,这真的很蹩脚,不是一个选择。我试过了:

  • 使用 $.ajax,并将 async 设置为 false
  • 使用睡眠功能
  • 警报框(在绝望中使用)

这是代码 - 有什么想法吗?:

$('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);

});
4

2 回答 2

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();
}

关于延迟的说明:您必须传递函数引用,而不是函数调用。这意味着您传递的函数名称不带括号。

于 2011-12-26T22:15:52.433 回答
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);
于 2011-12-26T22:16:09.890 回答