2011-02-12 22 views
6

Estoy probando un código comojQuery diferidos no trabaja

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

Esto funciona como se esperaba. Sin embargo, cuando lo escribo como:

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

sólo avisa "Inicio" y terminates.A ejemplo de trabajo se puede encontrar en http://jsfiddle.net/XQFyq/2/. ¿Qué estoy haciendo mal?

+0

'start()' no devuelve nada por lo que no puede usar el encadenamiento de aquí supongo. – pimvdb

+0

Bueno, incluso poner la búsqueda en prueba y comenzar desde la búsqueda no está ayudando. – Ashish

+0

'Test' simplemente no tiene los métodos correspondientes. ¿has mirado firebug/webinspector? – kirilloid

Respuesta

7

Test no es un deferred object, por lo que no tiene un método .then(). .when()IS a deferred object por lo que funciona cuando llamas al .when().

Su $.ajax() llamada ES un deferred object, por lo que si vuelve que como parte de su método de 'Test.start(), puede agregar .then() devoluciones de llamada (see example here), los .then() devoluciones de llamada se llamará una vez que la llamada AJAX se ha resuelto, es decir, ha devuelto sus datos, sin embargo, este no es realmente el uso correcto del objeto diferido, no creo. El siguiente es más la forma en que está destinado a ser utilizado creo:

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

ver su funcionamiento here

Si desea que los datos devueltos por ejemplo en showDiv() cambiarlo a showDiv(data) ... ..


Aquí es otro ejemplo de cómo se puede crear su propia deferred object en lugar de confiar en el deferred object de la llamada .ajax(). Esto es un poco más cerca de su original ejemplo - si usted quiere ver fracasar por ejemplo, cambiar la url para 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); 

actualización para responder a los comentarios:

En su version 11, no está diciendo el objeto diferido de una falla, por lo que nunca llamará a la devolución de llamada .fail(). Para rectificar esto, utilice la interpretación ajax si el .fail()(error:.......) para avisar al objeto diferido de una falla error: drf.reject - esto ejecutará la devolución de llamada .fail().

En cuanto a la razón por la que está viendo ShowMoreCode() tramo recto de distancia, es decir, los .then() llamadas son devoluciones de llamada, si se le pasa una cadena que representa una función como: .then(ShowDiv) una vez que llegue su turno la devolución de llamada se buscará una función con ese nombre . Si pasa una llamada a una función .then(someMoreCode('Ashish')), ejecutará la función. Pruébalo, cambia .then(showDiv) a .then(showDiv()) notarás que tan pronto como se ejecute el código, se mostrará el código de showDiv().

Si cambia .then(ShowMoreCode('Ashish')) a .then(ShowMoreCode), puede acceder a los datos devueltos desde la llamada $.ajax(). De esta manera:

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

Echa un vistazo aquí: working y NOT working .fail()

+0

Gracias o una respuesta detallada. Sin embargo, después de probar el código anterior, veo que el fallo todavía no se llama. Incluso cambié la URL a http://DONTsearch.twitter.com/search.json pero no tuve suerte. Una cosa más que noté en este código http://jsfiddle.net/ashishnjain/XQFyq/11/ fue que, la función algunaMoreCode se llama incluso antes del código de búsqueda. ¿No podemos encadenar algunosMoreCode para que se ejecuten después de que se haya completado todo el código? – Ashish

+0

Consulte la actualización de la respuesta que con suerte lo ayudará con su código. – Scoobler

+0

Gracias de nuevo por la explicación detallada. Sin embargo, su respuesta actualizada significa que no podemos conectar funciones personalizadas con valores personalizados que no están relacionados con la llamada ajax a la cadena. someMoreCode ('Ashish') fue solo un ejemplo. De hecho, tengo que mostrar otro div en mi código al responder la llamada ajax. Digamos que si obtengo un registro en respuesta, le muestro el div o si no, muestro una declaración personalizada de 'No records exists'. Pero finalmente, el someMoreCode debe ejecutarse el último. ¿Hay alguna manera de enganchar parámetros personalizados a la llamada ajax a la que se puede acceder desde algún Más Código como dijiste name.query? – Ashish