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