javascript - 如何嵌套 jquery.when 调用

标签 javascript ajax jquery asynchronous

我有一个函数可以加载报告的一部分。

// function to load section 
function loadSection(sectionId) {

    $.when(

        // Now load the specified template into the $overlay.
        loadTemplate(sectionId),

        // After the template is in place we need to identify all
        // the editable areas and load their content.
        loadEditables(sectionId)

    )
    .then(function () {

        // Now find all section link elements and wire them up.
        buildSectionLinks(),

        // Find all hover elements and attach the hover handlers.
        loadHovers()

    });

}

我们的想法是,我们将加载一个模板,然后遍历该模板以找到所有“可编辑项”,它们只是模板中用户提供的内容区域。一旦加载了模板和所有可编辑的内容,我们就会对标记进行一些处理,例如将点击事件绑定(bind)到某些元素。所有模板和可编辑的 ajax 调用都需要在处理发生之前完成。

loadTemplate(sectionId) 的调用与 jQuery.when 一起工作得很好,因为我只执行一个 ajax 调用。

// This function goes out to an AJAX endpoint and gets the specified
// report template and appends it to the overlay DIV.
function loadTemplate(sectionId) {
    return $.ajax({
        url: settings.templateUrl,
        data: { sectionId: sectionId },
        type: 'post',
        success: function (template) {
            $overlay.append(template);
        }
    });
}

loadEditables(sectionId) 函数实现起来并不那么简单,因为我必须遍历所有可编辑项并对每个可编辑项执行 ajax 调用。

// This function loads content for all editables defined in the template.
function loadEditables(sectionId) {
    // Grab all editables into a jQuery wrapped set.
    var $editables = $('#template .editable');

    // Loop through each editable and make an AJAX call to load its content.
    $editables.each(function () {
        var $editable = $(this);

        $.ajax({
            type: 'post',
            url: settings.editableUrl,
            data: {
                sectionId: sectionId,
                editableIndex: $editable.data('editableindex')
            },
            success: function (editable) {
                if (editable.hasData)
                    $editable.html(editable.content);
            }
        });
    });
}

loadTemplate 中,我能够简单地在函数中 return $.ajax(...) 来满足 $.when(...) 。在这里,我循环遍历包装的集合并为集合中的每个元素执行新的 ajax 调用。如何确保在触发处理函数(buildSectionLinks()loadHovers())之前完成所有这些调用?

最佳答案

将 promise 对象存储在一个数组中,然后使用 .apply将该数组传递给 $.when

function loadEditables(sectionId) {
    // Grab all editables into a jQuery wrapped set.
    var $editables = $('#template .editable'),
        defArr = [];

    // Loop through each editable and make an AJAX call to load its content.
    $editables.each(function () {
        var $editable = $(this);

        defArr.push($.ajax({
            type: 'post',
            url: settings.editableUrl,
            data: {
                sectionId: sectionId,
                editableIndex: $editable.data('editableindex')
            },
            success: function (editable) {
                if (editable.hasData)
                    $editable.html(editable.content);
            }
        }));
    });
    return $.when.apply($,defArr);
}

关于javascript - 如何嵌套 jquery.when 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12943645/

相关文章:

javascript - Handlebars.js:分配给模板时为空属性

javascript - 在 Javascript 中更新动画持续时间

javascript - 处理字符串上的多个条件

javascript - 在asp.net mvc中将json数据渲染到网格中

javascript - 淡入淡出对页面加载的影响

jquery - 如何使用jquery克隆表中的tr

javascript - Angular - 路由为什么我的 Controller 被调用两次

javascript - 使用 ajax 加载选项卡内容 onclick

javascript - 更新前验证字段

html - 如何将png二进制数据放入img标签中并显示为图像?