jQuery отложено не работает - PullRequest
       38

jQuery отложено не работает

6 голосов
/ 12 февраля 2011

Я пробую код как

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 Ответ

8 голосов
/ 12 февраля 2011

Test не является отложенным объектом , поэтому у него нет метода .then(). .when() IS a отложенный объект , следовательно, почему он работает при вызове .when().

Ваш $.ajax() вызов IS a отложенный объект , поэтому, если вы вернете это как часть вашего 'Test.start() метода, вы можете добавить .then() callbacks ( см. пример здесь ) , обратные вызовы .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(). Это немного ближе к исходному примеру - например, если вы хотите, чтобы он не работал, измените 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);

Обновление для ответа на комментарии:

В вашей версии 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()

...