jQuery推迟不工作

时间:2011-02-12 16:50:14

标签: javascript jquery ajax jquery-deferred

我正在尝试代码

function search(query) {
    var dfr = $.Deferred();
    $.ajax({
        url: "http://search.twitter.com/search.json",
        data: {
            q: query
        },
        dataType: 'jsonp',
        success: dfr.resolve
    });
    return dfr.promise();
}

Test = {
    start: function(){
        alert("Starting");
    }
};

function gotresults(data) {
    alert(data.max_id);
}

function showDiv() {
    $('<div />').html("Results received").appendTo('body');
}

$.when(search('ashishnjain'))
    .then(gotresults)
    .then(showDiv);

这可以按预期工作。但是当我把它写成:

Test.start()
    .then(search('ashishnjain'))
    .then(gotresults)
    .then(showDiv);

它只是警告“正在启动”并终止。可以在http://jsfiddle.net/XQFyq/2/找到一个工作示例。我做错了什么?

1 个答案:

答案 0 :(得分:8)

Test不是deferred object,因此它没有方法.then().when() 一个deferred object因此,当您拨打.when()时,它的工作原理。

您的$.ajax()来电一个deferred object,因此如果您将其作为'Test.start()方法的一部分返回,则可以添加.then()个回调see example here,一旦解析了ajax调用,就会调用.then()回调,即返回了它的数据,但这并不是正确使用的延迟对象我不认为。以下是我更相应的使用方式:

function searchTwitter(query){
    $.ajax({
            url: "http://search.twitter.com/search.json",
            data: {
                q: query
            },
            dataType: 'jsonp',
            success: function(data){return data;}
        })
        .then(gotresults)
        .then(showDiv)
        .fail(showFailDiv);
};

function gotresults(data) {
    alert(data.max_id);
}

function showDiv() {
    $('<div />').html("Results received").appendTo('body');
}

function showFailDiv() {
    $('<div />').html("Results <b>NOT</b> received").appendTo('body');
}

// Starting can be done with a click:

$("#searchTwitter").click(function(){
   searchTwitter($("#searchName").val()); 
});

// OR a static call:
searchTwitter("ashishnjain");

查看工作 here

如果您希望返回的数据例如showDiv(),请将其更改为showDiv(data) .....


以下是另一个示例,说明如何创建自己的deferred object,而不是依赖.ajax()来电的deferred object。这比原始示例更接近 - 例如,如果您希望看到它失败,请将网址更改为http://DONTsearch.twitter.com/search.json example here

var dfr;

function search(query) {
    $.ajax({
        url: "http://search.twitter.com/search.json",
        data: {
            q: query
        },
        dataType: 'jsonp',
        success: function(data){dfr.resolve(data);},
        error:  function(){dfr.reject();}
    });
}

Test = {
    start: function(){
        dfr = $.Deferred();
        alert("Starting");
        return dfr.promise();        
    }
};


function gotresults(data) {
    alert(data.max_id);
}

function showDiv() {
    $('<div />').html("Results received").appendTo('body');
}

function showFailDiv() {
    $('<div />').html("Results <b>NOT</b> received").appendTo('body');
}

Test.start()
    .then(search('ashishnjain'))
    .then(gotresults)
    .then(showDiv)
    .fail(showFailDiv);

更新以回复评论:

version 11中,您没有告诉延迟对象失败,因此它永远不会调用.fail()回调。要解决此问题,请使用ajax解释,如果.fail() error:.......告知延迟对象失败error: drf.reject - 这将运行{{1回调。

至于你看到.fail()直接运行的原因是,ShowMoreCode()调用是回调,如果你传递一个函数的字符串表示,如:.then()轮到回调将寻找具有该名称的函数。如果您将调用传递给函数.then(ShowDiv),它将运行该函数。试试吧,将.then(someMoreCode('Ashish'))更改为.then(showDiv),一旦代码运行,您就会注意到它会显示来自.then(showDiv())的代码。

如果您将showDiv()更改为.then(ShowMoreCode('Ashish')),则可以访问.then(ShowMoreCode)来电中返回的数据。像这样:

$.ajax()

在这里查看:workingNOT working .fail()