2011-02-12 157 views
6

我嘗試了代碼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); 

它只是提醒「啓動」和terminates.A工作示例可以在http://jsfiddle.net/XQFyq/2/找到。我究竟做錯了什麼?

+0

'開始(),所以你不能使用鏈接在這裏我想`不返回任何東西。 – pimvdb 2011-02-12 16:58:17

+0

即使把搜索放在測試中並從搜索開始並沒有幫助。 – Ashish 2011-02-12 17:03:14

回答

7

Test不是deferred object,所以它沒有方法.then().when()IS a deferred object因此,當您撥打.when()時,它會工作。

$.ajax()呼叫IS一個deferred object,因此,如果您返回,作爲您'Test.start()方法的一部分,您可以添加.then()回調see example here,一旦Ajax調用已經解決了.then()回調會被調用,即已經返回了它的數據,但是這並不是我認爲沒有的延遲對象的正確用法。下面是更多的則是打算如何使用,我相信:

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

看到它的工作here

如果你想在例如showDiv()其更改爲showDiv(data)返回的數據... ..


這是另一個如何創建自己的deferred object而不是依靠致電.ajax()致電。這是一個有點接近你原來的例子 - 如果你想看到它失敗例如,將URL更改爲http://DONTsearch.twitter.com/search.jsonexample here

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

更新回答的評論:

在您的version 11中,您沒有告訴延遲的失敗對象,因此它永遠不會調用.fail()回調。要糾正這種情況,如果.fail()error:.......建議延遲對象的失敗error: drf.reject - 這將運行.fail()回調,請使用ajax解釋。

至於你看到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); 
} 

到這裏看看:workingNOT working .fail()