使用deferred.done()函数

时间:2014-02-18 08:46:20

标签: jquery ajax jquery-deferred

我有以下功能:

function checkTag(dataVal) {
    return $.ajax({
        data: {input: dataVal}
        ...
    });
}

目前,在keyup上,该函数被调用为:

$("#element").on("keyup", function() {
    var tag = $(this).val();
    checkTag(tag).done(function(data) {
        ...
    });
});

这没有问题。但是,稍后在我的代码中,我想再次调用deferred.done()。因此,我创建了一个函数:

function checkTagDone(data) {
    ...
}

试图这样称呼:

checkTag(tag).done(checkTagDone(data));

并尝试过:

$.when(checkTag(tag)).done(checkTagDone(data));

但在两个实例中我都在控制台获得variable 'data' is not found。我明显误解了deferred.done的用法,但是必须有一种方法可以迭代同一个deferred.done,而不必复制代码。我可以在单个AJAX调用后找到支持多个deferred.done实例的文档,但在多个AJAX调用之后,我无处可寻找复制相同deferred.done的解决方案。

object htmlinputelement问题的相关jQuery:

function checkTagDone(data, tag) {    
    if (data) {
        ...
        //Create span around tag input
        $(".tree").last().append("<span class='tag'>"+tag+"</span>").fadeIn(500).val("");
        ...
    }
}

2 个答案:

答案 0 :(得分:2)

您需要将函数引用传递给done,并将tag的值传递给checkTag方法(因为我可以看到tag是一个keyup范围内的局部变量。)。

checkTag($("#element").val()).done(checkTagDone);

var tag = $("#element").val();
checkTag(tag).done(function (data) {
    checkTagDone(data, tag);
});

答案 1 :(得分:0)

瑞安,你似乎有两个选择:

保持事件处理程序不变,并触发keyup事件以对元素的当前值重新执行ajax

$("#element").trigger('keyup');

这可以在代码中的任何位置执行。没有范围问题,因为所有代码都可以访问DOM。

修改事件处理程序,使其在外部范围中保存最新的ajax承诺

var lastKeyupPromise;
...
$("#element").on('keyup', function() {
    lastKeyupPromise = checkTag($(this).val()).done(checkTagDone);
});

然后,代码中的其他地方:

if(lastKeyupPromise) { // safety is required as `lastKeyupPromise` may still be undefined
    lastKeyupPromise.done(checkTagDone);
}

这可以在代码中的任何位置执行,只要lastKeyupPromisecheckTagDone在范围内。

第二种方法的优点是:

  • 无需执行其他ajax请求。
  • 您不仅限于执行checkTagDone。您可以选择在代码中执行适当的任何操作。

例如:

if(lastKeyupPromise) {
    lastKeyupPromise.done(someOtherHandler);
}