jQuery推迟不工作

Ash*_*ish 6 javascript ajax jquery 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);
Run Code Online (Sandbox Code Playgroud)

这按预期工作.但是当我把它写成:

Test.start()
    .then(search('ashishnjain'))
    .then(gotresults)
    .then(showDiv);
Run Code Online (Sandbox Code Playgroud)

它只是警告"开始"并终止.可以在http://jsfiddle.net/XQFyq/2/找到一个工作示例.我究竟做错了什么?

Sco*_*ler 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");
Run Code Online (Sandbox Code Playgroud)

看到它在这里工作

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


这里是你如何可以创建自己的另一个例子递延对象,而不是依赖于递延对象的的.ajax()呼叫.这与原始示例稍微接近 - 例如,如果您希望看到它失败,请将URL更改为http://DONTsearch.twitter.com/search.json 示例:

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);
Run Code Online (Sandbox Code Playgroud)

更新回答评论:

在您的版本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);
}
Run Code Online (Sandbox Code Playgroud)

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