2012-06-01 18 views
12

Tengo una promesa $.ajax y deseo comprobar si mi respuesta (sintácticamente válida) contiene un error, lo que desencadena el estado rechazado en ese caso.Lanzar un error en el objeto diferido de jQuery

He trabajado con mi propia biblioteca de promesas que hace estas tareas fácilmente. Realmente no me gusta la implementación de jQuery Promise (cache) con su Deferred object y puede haber pasado por alto algo, porque rara vez lo uso. Creo que el camino a seguir es sólo con .then(), que parece ser bastante complicado:

return $.ajax(...).then(function success(response) { 
    var problem = hasError(response); 
    if (problem) { 
     var error = new $.Deferred; 
     error.reject(problem); 
     return error; 
    } else 
     return response; 
}); 

Esto debería devolver una promesa que es rechazado en caso de errores de red o problemas con la respuesta. Pero, ¿el retorno de un diferido rechazado es realmente el [único | mejor | más corto] camino a seguir?

También solicitaré ayuda sobre cómo tratar con esos "manejadores de respuestas que lanzan errores" en las opciones de ajax en sí mismos, no pude encontrar buena documentación sobre ellos.


Descargo de responsabilidad: No, no puedo cambiar las respuestas del servidor. El método de detección de problemas es sincrónico. No quiero utilizar otras bibliotecas, estoy particularmente interesado en la forma en que jQuery resuelve esto.

+0

bien, con '.then()' Me refería a la cosa que '.pipe()' hace en jQuery :-( – Bergi

+0

a partir de Jquery 1.8 tubería === luego – Plynx

+0

Sí, afortunadamente consiguieron al menos eso arreglado. – Bergi

Respuesta

31

ahora se actualiza para jQuery 1.8+

La forma más fácil para hacer frente a esto es ejecutar la respuesta de $.ajax través .then para filtrar basado en el éxito o fracaso de los datos.

$.ajax() 
    .then(function (response) { 
     return $.Deferred(function (deferred) { 
      var problem = hasError(response); 

      if (problem) { 
       return deferred.reject(problem) 
      } 

      deferred.resolve(response); 
     }).promise(); 
    }); 

entonces se podría devolver esta nueva promesa a cualquier código de llamada consumiría esto:

var request = function() { 
    return $.ajax() 
     .then(function (response) { 
      return $.Deferred(function (deferred) { 
       var problem = hasError(response); 

       if (problem) { 
        return deferred.reject(problem) 
       } 

       deferred.resolve(response); 
      }).promise(); 
     }); 
}; 

request() 
    .done(function (response) { 
     // handle success 
    }) 
    .fail(function (problem) { 
     // handle failure 
    }); 
+0

¿Cuál es la diferencia entre la tubería y luego? – Bergi

+1

'pipe' le permite filtrar los valores diferidos antes de que se envíen a cualquier manejador de promesa registrado. 'then' en realidad solo se usa para registrar manejadores cuando una promesa se resuelve o rechaza. – Eli

+1

No, [por especificación] (http://webcache.googleusercontent.com/search?q=cache%3awiki.commonjs.org/wiki/Promises/A) .then() haría exactamente eso. ¿O acaso jQuery tiró esto y cambió los nombres de los métodos? – Bergi

Cuestiones relacionadas