jquery - 如何将回调附加到附加到延迟对象的延迟对象?

标签 jquery jquery-deferred

我有一系列 ajax 请求,支持一系列级联下拉选择列表。当您在第一个下拉列表中选择一个值时,会触发一个请求来填充第二个下拉列表,当该请求完成(并且下拉列表已填充)时,会触发下一个请求来填充第三个下拉列表,依此类推。

这些请求链的形成方式有一些变化,因此我希望使用 jQuery Deferred 对象来组装请求。

我知道如何将第二个请求链接到第一个请求,但我不知道如何将第三个请求链接到第二个请求。

function Step1() { return $.ajax(<foo>);}
function Step2() { return $.ajax(<foo>);}
function Step3() { return $.ajax(<foo>);}

$(function() {
   Step1().then(Step2).then(Step3);
});

意图是当 Step2 解析时触发 Step3,但 .then(Step2) 返回的延迟对象来自 Step1,因此将 Step3 添加为 Step1 的回调。

我想如果你看this jsFiddle sample,我想做什么会更清楚。 。 编辑:Here是同一个脚本,但在第二次调用中添加了延迟,以使其更加明显。

最佳答案

$(function() {
    $.when(Step1).then(function() {
         $.when(Step2).then(Step3);
    });
});

对于错误处理,我建议您将 Stepn 重写为:

function Stepn() { 
    return $.ajax(<foo>).fail(function() {
         // handle failure
    });
}

使用这种格式的回调可以让您做您想做的事情。如果步骤超过 5 个,缩进就会变得一团糟,为此构建一个队列可能是值得的。

这里是直播 example

var Queue = function() {
    var q = [];
    var that = this;

    // If items in queue then run them.
    function moveNext() {
        if (q.length > 0) {
            that.runItem();
        }
    }

    // run first item in queue
    this.runItem = function() {
        // get item
        var item = q.shift();
        // when deferred object then run then ...
        $.when(item.item).then([item.options.done, function() {
            // item finished, move to next.
            moveNext();
        }], [item.options.fail, function() {
            // if run item always then move next on failure.
            if (item.options.always) {
                moveNext();
            }
        }]);
    };

    this.add = function(def, options) {
        // if array then call add on each item in array
        if ($.isArray(def)) {
            for (var d in def) {
                this.add(d, options);
            }
            // return as we are done.
            return this;
        }
        // push item onto array
        q.push({
            item: def,
            options: options
        });
        // if items & not delay then run item.
        if (q.length === 1 && !options.delay) {
            this.runItem();
        }
        // enable jQuery style chaining \o/
        return this;
    };
};

Queue.add([def, def, ...], options) 将一个延迟项目或一组延迟项目添加到队列中。可以与单个延迟项或数组一起使用。选项图如下

{
    "delay" : Boolean, // if true do not run the item in the queue after appending it.
    "done" : Function, // optional done call back
    "fail" : Function, // optional fail call back
    "always": Boolean // if true run the next item in the queue even if this item fails.
}

Queue.runItem,一个运行队列中下一个项目的函数。内部调用,可以与延迟属性手动连接使用。

关于jquery - 如何将回调附加到附加到延迟对象的延迟对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5505828/

相关文章:

jquery - JavaScript 未定义且 jQuery 延迟

javascript - 如何从已解析的 jQuery.Deferred() 中获取值(value)?

javascript - jQuery : How can showint text and hide then showing another?

javascript - 如何删除 Ember 对象的内容或将其设置为 null?

jquery - 在 Bootstrap 工具提示中显示长文本

javascript - 返回一个空洞的 promise

jquery - 延迟 getJSON 的返回未定义

javascript - 我可以将 Promises 传递给 jQuery.when() 还是只传递给 Deferreds?

javascript - Jquery排序表 ->文本前的数字

javascript - 在 jQuery 中获取 URL 并创建 ajax 后链接