小编典典

jQuery Deferred无法正常工作

ajax

我正在尝试一个代码

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


阅读 225

收藏
2020-07-26

共1个答案

小编典典

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更改为
example

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()回调。为了解决这个问题,如果.fail()
_(error:.......)_建议延迟对象失败,请使用ajax解释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()

2020-07-26