如何在 .each 循环内的 Jquery 回调完成后执行函数

How to execute a function after Jquery callbacks inside .each loop have comepleted

我有一个调用 JQuery.each() 的函数。然后调用第三方函数 (Devexpress GetRowValues()),执行回调。 .each 完成后,我必须调用 DoSuccess() 并传入数组 rv。 问题在于 RVGridCB() 在 DoSuccess() 之后执行。如何确保在执行 DoSuccess() 之前完成 .each 循环中的所有回调?

function ReturnValueAndClose(ctrl) {
    var rv = new Array();

    $('[id*="chkCopy"]').each(function () {
        try {
            var v = $(this).val();
            if (v == 'C') {               
                var id = eval($(this)[0].id).id;
                var i = id.indexOf('chkCopy_') + 8;               
                var rowIndex = parseInt(id.substr(i, 4));
                 wgdFormFile.GetRowValues(rowIndex, "Name;Description;Details", RVGridCB);           
            }

        } catch (e) {
        }

    });   

     function RVGridCB(values) {           
            rv.push(values);  
        }

     DoSuccess(new Array('1', rv));
     return false;    
}

我认为你可以使用 deferred 个对象。

为每个回调 RVGridCB 和回调调用内部 dfd.resolve().

创建一个包含延迟对象的数组

在done回调$.when.apply($, deferred_arr).done(function () ...);中可以调用doSuccess(...).

这是一个带有超时的延迟示例,用于模拟异步事件。您也可以在 jsFiddle.

找到它

编辑 2015 年 2 月 4 日:

我为每个延迟对象添加了一个完成回调,以更好地显示每个超时的结束。

var asyncEvent = function (n) {
    var dfd = $.Deferred();
    var duration = n * 1000;

    setTimeout(function () {
        dfd.resolve(n);
    }, duration);
    
    dfd.done(function(n) {
        var now = new Date();
        //console.log('end time', n, now);
        $('body').append('end time of task ' + n + ': '+ now.toString() + '<br/>');
    });
    
    return dfd;
};

var thingsToDo = [1, 2, 3, 4];
var def = [];

var events = function () {
    $.each(thingsToDo, function (index, value) {
        var now = new Date();
        $('body').append('start time: ' + now.toString() + '<br/>');
        //console.log('called', value);
        def.push(asyncEvent(value));
    });
    return def;
};

$.when.apply($, events())
    .done(function (status) {
    //console.log(def);
    var now = new Date();
    console.log('end time', now);
    $('body').append('end time: ' + now.toString() + '<br/>');
    $('body').append('all events done');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

查看 jquery 延迟对象。

如果您的 GetRowValues 方法 returns Deferred 对象,您可以尝试将它们存储在数组中

var valuesDone = [];

$('[id*="chkCopy"]').each(function(){

    valuesDone.push( 
        wgdFormFile.GetRowValues(rowIndex, "Name;Description;Details").done(RVGridCB) 
    );

})

之后,使用jquery '$.when()' 方法,当所有'values are done'.

设置回调
$.when.apply($, valuesDone).done(function(){ DoSuccess(new Array('1', rv)); })

如果您的 GetRowValues 方法没有return延迟,您可以创建外观函数:

function GetRowValues(rowIndex){
    var d = new $.Deferred();
    wgdFormFile.GetRowValues(rowIndex, "Name;Description;Details", function(){ d.resolve() });
    return d;
}