javascript jQuery延迟不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4979258/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 15:32:55  来源:igfitidea点击:

jQuery Deferred not working

javascriptjqueryajaxjquery-deferred

提问by Ashish

I am trying out a code as

我正在尝试一个代码

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

This works as expected. However when I write it as:

这按预期工作。但是,当我将其写为:

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

it just alerts "Starting" and terminates.A working example can be found at http://jsfiddle.net/XQFyq/2/. What am I doing wrong?

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

回答by Scoobler

Testis not a deferred object, so it does not have a method .then(). .when()ISa deferred objecthence why it works when you call .when().

Test不是延迟对象,因此它没有方法.then().when()一个延迟对象,因此当您调用.when().

Your $.ajax()call ISa deferred object, so if you return that as part of your 'Test.start()method, you can add .then()callbacks (see example here), the .then()callbacks will be called once the ajax call has been resolved, i.e. has returned its data, however this isn't really the correct use of the deferred object I don't think. The following is more how it is intended to be used I believe:

您的$.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");

See it working here

看到它在这里工作

If you want the returned data in for example showDiv()change it to showDiv(data).....

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



Here is another example of how you could create your own deferred objectinstead of relying on the deferred objectof the .ajax()call. This is a little closer to your original example - if you want to see it fail for example, change the url to http://DONTsearch.twitter.com/search.jsonexample here:

这里是你如何可以创建自己的另一个例子递延对象,而不是依赖于递延对象的的.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);


Update to answer the comments:

更新以回答评论:

In your version 11, you are not telling the deferred object of a failure, so it will never call the .fail()callback. To rectify this, use the ajax interpretation if the .fail()(error:.......)to advise the deferred object of a failure error: drf.reject- this will run the .fail()callback.

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

As for the reason you are seeing ShowMoreCode()run straight away is, the .then()calls are callbacks, if you pass it a string representation of a function like: .then(ShowDiv)once its turn comes the callback will look for a function with that name. If you pass a call to a function .then(someMoreCode('Ashish'))it will run the function. Try it, change .then(showDiv)to .then(showDiv())you will notice as soon as the code runs, it will show the code from showDiv().

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

If you change .then(ShowMoreCode('Ashish'))to .then(ShowMoreCode), you can access the returned data from the $.ajax()call. Like this:

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

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

Take a look here: workingand NOT working .fail()

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