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

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

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

Решение

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() вызов. Это немного ближе к исходному примеру - например, если вы хотите, чтобы он не работал, измените 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()

Другие вопросы по тегам