when then ejemplo done await async another after jquery promise jquery-deferred

ejemplo - jQuery difiere y promete-.then() vs.done()



jquery.when ejemplo (8)

He estado leyendo sobre jQuery aplazados y promesas y no puedo ver la diferencia entre usar .then() y .done() para las devoluciones de llamada exitosas. Sé que Eric Hynds menciona que .done() y .success() asignan a la misma funcionalidad, pero supongo que también .then() ya que todas las devoluciones de llamada se invocan al completar una operación exitosa.

¿Alguien puede por favor iluminarme al uso correcto?

Muchas gracias


aplazado.done ()

agrega manejadores para llamar solo cuando se resuelve Aplazado . Puede agregar múltiples devoluciones de llamada para ser llamado.

var url = ''http://jsonplaceholder.typicode.com/posts/1''; $.ajax(url).done(doneCallback); function doneCallback(result) { console.log(''Result 1 '' + result); }

También puedes escribir arriba de esta manera,

function ajaxCall() { var url = ''http://jsonplaceholder.typicode.com/posts/1''; return $.ajax(url); } $.when(ajaxCall()).then(doneCallback, failCallback);

Deferred.then ()

agrega manejadores para llamar cuando se aplaza, se rechaza o aún está en curso Aplazado .

var url = ''http://jsonplaceholder.typicode.com/posts/1''; $.ajax(url).then(doneCallback, failCallback); function doneCallback(result) { console.log(''Result '' + result); } function failCallback(result) { console.log(''Result '' + result); }


En realidad, hay una diferencia bastante crítica, en la medida en que los aplazados de jQuery están destinados a ser una implementación de Promises (y jQuery3.0 en realidad intenta llevarlos a especificaciones).

La diferencia clave entre hecho / hecho es que

  • .done() SIEMPRE devuelve la misma Promesa / valores ajustados con los que comenzó, independientemente de lo que haga o devuelva.
  • .then() siempre devuelve una NUEVA Promesa, y usted está a cargo de controlar qué Promesa se basa en qué devolvió la función que pasó.

Traducido de jQuery a las promesas ES2015 nativas, .done() es algo así como implementar una estructura de "tap" alrededor de una función en una cadena de Promise, en el sentido de que, si la cadena está en el estado de "resolución", pasará un valor a una función ... pero el resultado de esa función NO afectará a la cadena en sí.

const doneWrap = fn => x => { fn(x); return x }; Promise.resolve(5) .then(doneWrap( x => x + 1)) .then(doneWrap(console.log.bind(console))); $.Deferred().resolve(5) .done(x => x + 1) .done(console.log.bind(console));

Ambos registrarán 5, no 6.

Tenga en cuenta que utilicé done y doneWrap para hacer el registro, no .then. Eso es porque las funciones de console.log en realidad no devuelven nada. ¿Y qué pasa si pasas por una función que no devuelve nada?

Promise.resolve(5) .then(doneWrap( x => x + 1)) .then(console.log.bind(console)) .then(console.log.bind(console));

Eso se registrará:

5

indefinido

¿Que pasó? Cuando utilicé .then y le pasé una función que no devolvió nada, el resultado implícito era "indefinido" ... que por supuesto devolvió una Promesa [indefinida] al siguiente método, que se registró como indefinido. Así que el valor original con el que comenzamos se perdió básicamente.

.then() es, en el fondo, una forma de composición de función: el resultado de cada paso se utiliza como argumento para la función en el siguiente paso. Es por eso que .done es mejor considerado como un "toque" -> en realidad no es parte de la composición, solo es algo que se escapa del valor en un determinado paso y ejecuta una función en ese valor, pero que en realidad no se altera. La composición de ninguna manera.

Esta es una diferencia fundamental, y probablemente hay una buena razón por la que las Promesas nativas no tienen un método .done implementado por sí mismos. No tenemos que adivinar por qué no hay un método .fail, porque es aún más complicado (es decir, .fail / .catch NO son espejos de .done / .then -> funciones en .catch que devuelven valores sin valor) "permanecer" rechazado como los pasados ​​a .then, resuelven!)


Hay un mapa mental muy simple en respuesta que fue un poco difícil de encontrar en las otras respuestas:


Las devoluciones de llamada adjuntas a done() activarán cuando se resuelva el aplazamiento. Las devoluciones de llamada adjuntas a fail() activarán cuando se rechace el aplazado.

Antes de jQuery 1.8, then() era solo azúcar sintáctica:

promise.then( doneCallback, failCallback ) // was equivalent to promise.done( doneCallback ).fail( failCallback )

A partir de 1.8, then() es un alias para pipe() y devuelve una nueva promesa, consulte here para obtener más información sobre pipe() .

success() y error() solo están disponibles en el objeto jqXHR devuelto por una llamada a ajax() . Son alias simples para done() y fail() respectivamente:

jqXHR.done === jqXHR.success jqXHR.fail === jqXHR.error

Además, done() no se limita a una sola devolución de llamada y filtrará las no funciones (aunque hay un error con las cadenas en la versión 1.8 que debería solucionarse en la versión 1.8.1):

// this will add fn1 to 7 to the deferred''s internal callback list // (true, 56 and "omg" will be ignored) promise.done( fn1, fn2, true, [ fn3, [ fn4, 56, fn5 ], "omg", fn6 ], fn7 );

Lo mismo vale para fail() .


También hay una diferencia en la forma en que se procesan los resultados de retorno (su encadenamiento llamado, done no encadena mientras produce cadenas de llamadas)

promise.then(function (x) { // Suppose promise returns "abc" console.log(x); return 123; }).then(function (x){ console.log(x); }).then(function (x){ console.log(x) })

Los siguientes resultados serán registrados:

abc 123 undefined

Mientras

promise.done(function (x) { // Suppose promise returns "abc" console.log(x); return 123; }).done(function (x){ console.log(x); }).done(function (x){ console.log(x) })

Obtendrá lo siguiente:

abc abc abc

---------- Actualización:

Por cierto Olvidé mencionar que si devuelve una Promesa en lugar de un valor de tipo atómico, la promesa externa esperará hasta que la promesa interna se resuelva:

promise.then(function (x) { // Suppose promise returns "abc" console.log(x); return $http.get(''/some/data'').then(function (result) { console.log(result); // suppose result === "xyz" return result; }); }).then(function (result){ console.log(result); // result === xyz }).then(function (und){ console.log(und) // und === undefined, because of absence of return statement in above then })

De esta manera, resulta muy sencillo componer operaciones asíncronas paralelas o secuenciales, tales como:

// Parallel http requests promise.then(function (x) { // Suppose promise returns "abc" console.log(x); var promise1 = $http.get(''/some/data?value=xyz'').then(function (result) { console.log(result); // suppose result === "xyz" return result; }); var promise2 = $http.get(''/some/data?value=uvm'').then(function (result) { console.log(result); // suppose result === "uvm" return result; }); return promise1.then(function (result1) { return promise2.then(function (result2) { return { result1: result1, result2: result2; } }); }); }).then(function (result){ console.log(result); // result === { result1: ''xyz'', result2: ''uvm'' } }).then(function (und){ console.log(und) // und === undefined, because of absence of return statement in above then })

El código anterior emite dos solicitudes http en paralelo, lo que hace que las solicitudes se completen antes, mientras que debajo de esas solicitudes http se ejecutan de manera secuencial, lo que reduce la carga del servidor.

// Sequential http requests promise.then(function (x) { // Suppose promise returns "abc" console.log(x); return $http.get(''/some/data?value=xyz'').then(function (result1) { console.log(result1); // suppose result1 === "xyz" return $http.get(''/some/data?value=uvm'').then(function (result2) { console.log(result2); // suppose result2 === "uvm" return { result1: result1, result2: result2; }; }); }); }).then(function (result){ console.log(result); // result === { result1: ''xyz'', result2: ''uvm'' } }).then(function (und){ console.log(und) // und === undefined, because of absence of return statement in above then })


.done() termina la cadena de promesa, asegurándose de que nada más pueda adjuntar más pasos. Esto significa que la implementación de la promesa jQuery puede lanzar cualquier excepción no manejada, ya que nadie puede manejarlo usando .fail() .

En términos prácticos, si no planea adjuntar más pasos a una promesa, debe usar .done() . Para más detalles, vea por qué se deben hacer promesas.


.done() tiene solo una devolución de llamada y es la devolución de llamada exitosa

.then() tiene devoluciones de llamada .then() y fallidas

.fail() solo tiene una devolución de llamada fallida

así que depende de ti lo que debes hacer ... ¿te importa si tiene éxito o si falla?


then() siempre significa que se llamará en cualquier caso. Pero los parámetros que pasan son diferentes en las diferentes versiones de jQuery.

Antes de jQuery 1.8, then() es igual a done().fail() . Y todas las funciones de devolución de llamada comparten los mismos parámetros.

Pero a partir de jQuery 1.8, then() devuelve una nueva promesa, y si tiene un valor devuelto, pasará a la siguiente función de devolución de llamada.

Veamos el siguiente ejemplo:

var defer = jQuery.Deferred(); defer.done(function(a, b){ return a + b; }).done(function( result ) { console.log("result = " + result); }).then(function( a, b ) { return a + b; }).done(function( result ) { console.log("result = " + result); }).then(function( a, b ) { return a + b; }).done(function( result ) { console.log("result = " + result); }); defer.resolve( 3, 4 );

Antes de jQuery 1.8, la respuesta debería ser

result = 3 result = 3 result = 3

Todo el result toma 3. Y then() función then() siempre pasa el mismo objeto diferido a la siguiente función.

Pero a partir de jQuery 1.8, el resultado debería ser:

result = 3 result = 7 result = NaN

Debido a que la primera función then() devuelve una nueva promesa, y el valor 7 (y este es el único parámetro que se transmitirá) se pasa al siguiente final done() , por lo que el segundo escrito done() escribe el result = 7 . El segundo then() toma 7 como el valor de a y toma undefined como el valor de b , por lo que el segundo then() devuelve una nueva promesa con el parámetro NaN, y el último done() imprime NaN como su resultado.