将$ .when()和.done()与jQuery的$ .each一起使用

时间:2013-06-09 12:16:38

标签: jquery ajax

我有一个页面,我在两个异步调用数据库中创建一个客户(公司)及其联系人。应在客户之后保存联系人,因为它需要包含在服务器响应中的客户ID。此外,完成所有操作后,会重定向到相应的新客户页面。

原样,即使在保存任何联系人之前也会发生重定向。我尝试使用jQuery的$.when().done(),但它不起作用,因为.when()和回调之间存在脱节。如何在这种情况下使其工作?

function saveAll() {
    createCustomer();
    createContacts();
    var url = "<newCustomerDetailPage>";    // redirect when all is done
    window.location = url;
}


function callback(result) {
    if (result) {
        // do something
    } else {
        // do something else
    }
}


function errorHandler(error) {
    // do something
}


function createCustomer() {       // Create 1 new customer
    // prep fields
    var client = new toolkit.Client();
    client.create(<fields>, callback, errorHandler);
}


function createContacts() {       // Create 1 or more new contacts
    $('.row').each(function() {
        // prep fields
        createContact(fields);
    }
}


function createContact(fields) {      // Create 1 new contact
    var client = new toolkit.Client();
    client.create(<fields>, callback, errorHandler);
}


function handleResult(result, callback, errorHandler) {
    if (blah...)
        callback(result)
    else
        errorHandler(error)
}

toolkit.Client:

toolkit.Client = function(){}

toolkit.Client.prototype.create = function(fields, callback, errorHandler) {
    // async call to database 
    function(result){        // handle server response
        handleResult(result, callback, errorHandler);
    }
}

请注意,client.create一次只能保存一条记录。

已经尝试过:

var actions = [];

function createContacts() {       // Create 1 or more new contacts
    $('.row').each(function() {
        // prep fields
        actions.push(function(){createContact(fields);});
    }
}

function saveAll() {
    createCustomer();
    createContacts();
    $.when.apply($,actions).done(function(){
        var url = "<newCustomerDetailPage>";    // redirect when all is done
        window.location = url;
    });
}

2 个答案:

答案 0 :(得分:1)

您可以使用promise

等待每个循环的结束
var actions = [];

function createContacts(callback) {       // Create 1 or more new contacts
    $('.row').each(function() {
        // prep fields
        actions.push(function(){createContact(fields);});
    }.promise().done(callback);
}

function saveAll() {
    createCustomer();
    createContacts(function(){
        $.when.apply($,actions).done(function(){
            var url = "<newCustomerDetailPage>";    // redirect when all is done
            window.location = url;
        });
    });

}

答案 1 :(得分:0)

理想情况下,您的client.create应该返回一个延迟对象,因为他是唯一一个负责创建联系人的方法,而且他是唯一可以解决它的方法:

toolkit.Client.prototype.create = function(fields, callback, errorHandler) {
    var def = $.Deferred();
    // async call to database 

    //resolve def when the result is ready
    //def.resolve or def.refect();

    return def;
}

createContact也必须返回结果:

function createContact(fields) {      // Create 1 new contact
    var client = new toolkit.Client();
    return client.create(<fields>, callback, errorHandler);
}

然后你可以这样做:

function createContacts() {       // Create 1 or more new contacts
    var actions = [];
    $('.row').each(function() {
        // prep fields
        actions.push(createContact(fields));
    }

    return actions;
}

function saveAll() {
    createCustomer();
    $.when.apply($, createContacts()).done(function(){
        var url = "<newCustomerDetailPage>";    // redirect when all is done
        window.location = url;
    });
}
相关问题