¿Cuál es la diferencia entre rechazar y cumplir una promesa?
ES6 y jQuery tienen Deffered y Promise, pero son ligeramente diferentes. Sin embargo, su funcionalidad se puede describir simplemente en dos frases.
El disparador definido se resuelve o rechaza.
¿Qué debo hacer después de declarar una resolución o rechazo en una promesa (callback)?
En jQuery
var deferred = $. diferido(); var promesa = diferido promesa();
En ES6.
var diferido = promesa . defer(); var promesa = defered.promise
MDN anunció que Deferred fue declarado caducado en Gecko 30 y ya no se puede usar. con una nueva Promesa (). New Promise() se explicará más adelante.
Aplazamiento/promesa de jQuery
El objeto Promise más utilizado en jQuery se devuelve mediante $. ajax() y los métodos más utilizados se realizan, fallan y siempre en lugar de entonces. Excepto dólares. ajax(), jQuery también proporciona llamadas Ajax simplificadas, como $. obtener(),$. publicación() y $. getJSON(), que devuelve un objeto Promise, al igual que el valor de retorno de $. ajax().
En realidad, USD. ajax() devuelve un objeto jqXHR. Pero jqXHR implementa la interfaz Promise de jQuery, por lo que también es un objeto Promise.
Done(), fail() y siempre()
Done() agrega una devolución de llamada a deferred.resolve(), y fail() agrega una devolución de llamada a deferred.reject( ). Por lo tanto, cuando la llamada Ajax tiene éxito, se ejecuta la devolución de llamada agregada por done(), y cuando la llamada falla, se ejecuta la devolución de llamada agregada por fail(). Pero independientemente del éxito o el fracaso, se ejecutará la devolución de llamada agregada por siempre ().
Aquí done(), fail() y always() agregan devoluciones de llamada en forma de eventos similares, es decir, no importa cuántas veces done(), fail() o always() se ejecutan, agregan Las devoluciones de llamada se ejecutarán secuencialmente bajo condiciones limitadas.
En general, Ajax se ejecuta así.
//Desactivar botón para evitar enviar $ ("# thebutton "). Repita los accesorios ({disabled: true}); // Llame a Ajax para enviar datos, asumiendo datos JSON var jqxhr = $. Ajax("hacer/ejemplo", {tipo: "publicar", tipo de datos: "JSON", datos: getformdata()}) retorno; done(function(JSON object){//Ajax llamó exitosamente a console.log("datos traídos exitosamente", objeto JSON);}).fail(function() {//Ajax no pudo llamar a console.log ("falló") } ). always(function(){// No importa si tiene éxito o no, se ejecutará para cancelar el estado deshabilitado del botón $ ("# thebutton "). prop({ deshabilitado: false }); }); /p>
Lo anterior es el uso más común y de uso común, pero escribir Ajax de esta manera en un proyecto es un poco agotador. Con un poco de acuerdo y encapsulación, será mucho más fácil de usar.
Primero, supongamos que definimos el JSON devuelto en el siguiente formato:
{"code": "int, 0 indica éxito, otros valores indican error", "message": "string, mensaje adicional, opcional "," data": "objeto, datos adicionales, opcional}
Luego defina un método ajax para la aplicación pública del proyecto
app.ajax = function(button. , URL, datos){ if(botón){ botón . prop(" deshabilitado ", verdadero } return $. )[if(JSON . code!== 0) {showError(json.message || "Error de operación");} }).fail(function() {showError("Error del servidor, inténtelo de nuevo más tarde"); }).always(function(){ if(button){ button . prop(" deshabilitado ", false); } } } // Llamar a app.ajax ("do/example", getformdata(). done( Función (JSON) {if (JSON.code = = = 0){//Solo es necesario manejar la situación correcta} });
Pero todavía es un poco incómodo, si json.code == = no es necesario 0 es mejor. Esto... se puede manejar con aplazamientos:
app.ajax = function(button, url, data){ if(button){ prop(" deshabilitado ". , verdadero); } var diferido = $. diferido(); $.ajax(url, { tipo: "publicación", tipo de datos: "JSON", datos: datos }). .código! == 0) {showError(json.message || "Error de operación"); diferido (). Error del servidor, inténtelo de nuevo más tarde"); diferido. rechazar(); }).always(function(){ if(button){ botón. prop("disabled",false); } }); return diferido. promesa ( ); }; // Llamar a app.ajax ("hacer/ejemplo", getformdata()). done(function(JSON){//JSON. code == 0 siempre mantiene//procesa json.data normalmente});
Tenga en cuenta que el objeto jqXHR resultante de $ no se devuelve directamente. ajax(), devuelve el objeto de promesa del objeto diferido recién creado.
Después de revisar Ajax, debemos ir al grano y encontrar el lugar donde jQuery Promise y ES6 Promise están relativamente cerca: entonces().
jQuery deferred.then()
Antes de jQuery 1.8 (excluyendo 1.8, como jQuery 1.7.2), deferred.then() es una combinación de done() y fail( ) azúcar sintáctico juntos. JQuery modificó el comportamiento de deferred.then() en la versión 1.8, haciendo que then() se comporte como Promise. En la documentación de jQuery, podemos ver los cambios en la versión 1.8: eliminar la devolución de llamada, reemplazada por filtro:
//Versión agregada: 1.5, eliminada: 1.8 diferida y luego (devoluciones de llamada realizadas, devoluciones de llamadas fallidas) // Versión. agregado: 1.7, eliminado: 1.8 diferido entonces (devoluciones de llamada hechas, failCallbacks [, ProgressCallbacks]) // Versión agregada: 1.8 diferido entonces (filtro hecho [, failFilter] [, ProgressFilter])
Puedes. simplemente piense en una devolución de llamada como un evento y el valor no cambiará después de la devolución de llamada, a diferencia de un filtro, el valor pasado al filtro y devuelto por el filtro puede haber cambiado; Pongamos un ejemplo para ilustrar.
var diferido = $. diferido(); var promesa = diferido . promesa(); entonces(función(v){ consola . log(` luego con $ { v } `); }).done(función(v){ consola . log( ` hecho con $ { v } `) }); deferred . resolve(" resuelto ATA ");
El resultado en jQuery 1.7.2
Luego completa con resolveData
El resultado en jQuery 1.8.0
Luego use resolveData para completar indefinido
Como se puede ver en lo anterior, jQuery's deferred.then() y ES6 Promise .entonces La semántica de () es básicamente la misma. Si el app.ajax anterior se reemplaza con la implementación then(), ayudará a comprender ES6 Promise.
app.ajax = función(botón, url, datos) { if (botón) { botón prop (" deshabilitado ", verdadero } return $. ajax (url, {tipo: "publicación", tipo de datos: "JSON", datos: datos}). entonces(función(json) { if (json.code! == 0) {showError(json.message || "Error de operación"); return $.Delay().Reject().Promise(); } else { return $.deferred().resolve(json); } }, function() {showError("Error del servidor, inténtalo de nuevo más tarde"); deferred.reject() ).always(function() { if(button) { botón . prop(" deshabilitado ", falso); } } }; //El método de llamada no ha cambiado.
Puedes usar done o puedes usar la aplicación. Ajax("hacer/ejemplo", obtener datos de formulario()). Listo (función (JSON) {//JSON. código == 0 siempre se mantiene //Simplemente procesa json.data normalmente}); de la promesa jQuery a la promesa ES6
El código anterior es demasiado largo, refine. eso La parte clave (señal, no se puede ejecutar).
var promesa = $. Ajax(); promesa.entonces(función(datos) { //El análisis devuelve datos.código? Nueva promesa().reject(): Nueva promesa().Resolve(datos); //Si no hay problema, devuelve un nueva promesa, use datos para resolver. // También puede devolver datos directamente, // dejar que la parte de análisis pueda recibir datos}, function(){//rejected }); llamar a la promesa de fase then(function. data){ //procesar datos });
Tal vez no lo hayas notado, pero el código anterior es básicamente la promesa de ES6. Ahora reescriba oficialmente el código esquemático anterior usando ES6 Promise.
var Promise = new Promise(función(resolver, rechazar) { $. ajax(). Then (resolver, rechazar); // ¿No entiendes la oración anterior? Entonces definitivamente la entenderás // $. Ajax(). entonces (función (datos) { // analizar (datos); // }, función () { // rechazar (); // } }); data.code?promesa.reject(): promesa.resolve(data); // Aquí Promise.resolve(data) también se puede reemplazar directamente por data}); Processing Data}) permanece sin cambios;
Bueno, no hay mucha diferencia. Antes de darme cuenta, ¡estaba comprometido con ES6!
La promesa de ES6
Lo anterior ha revelado la promesa de ES6, ahora solo necesitamos enumerar los métodos comúnmente utilizados como referencia.
Tenga en cuenta que la promesa en minúscula representa un objeto Promesa.
Nueva Promesa (ejecutor), genera un nuevo objeto Promesa.
gt` ejecutor(resolver, rechazar)` gt; "ejecutor", "resolver" y "rechazar" son todas funciones. En "ejecutor", maneje correctamente los datos devueltos llamando a "resolve()" y maneje las excepciones directamente a través de "ThrownnewError()" o "reject()".
Promise.resolve(data), genera un objeto Promise y lo resuelve.
Promise.reject(), genera un objeto Promise y lo rechaza.
Garantizado. Luego (cuando se resuelva, cuando se rechace), luego... continúe procesando.
El azúcar sintáctico de promesa.catch(onReject), project.then(null, onReject) es similar (pero diferente) al promet.fail() de jQuery.