6

我正在尝试一个代码

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/找到一个工作示例。我究竟做错了什么?

4

1 回答 1

8

Test不是延迟对象,所以它没有方法.then().when() 一个延迟对象,因此为什么它在您调用.when().

您的$.ajax()调用一个延迟对象,因此如果您将其作为'Test.start()方法的一部分返回,则可以添加.then()回调请参见此处的示例.then()一旦 ajax 调用被解决,即返回其数据,回调将被调用,但是这是我不认为延迟对象的正确使用。以下是我相信的更多使用方式:

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");

看到它在这里工作

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


这是另一个示例,说明如何创建自己的延迟对象而不是依赖调用的延迟对象.ajax()。这更接近您的原始示例 - 例如,如果您想看到它失败,请在http://DONTsearch.twitter.com/search.json 此处将 url 更改为示例

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);

更新以回答评论:

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

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

如果更改.then(ShowMoreCode('Ashish')).then(ShowMoreCode),则可以访问$.ajax()调用返回的数据。像这样:

function someMoreCode(name) {
    alert('Hello ' + name.query);
}

看看这里:工作不工作.fail()

于 2011-02-12T20:20:50.983 回答