Saltar al contenido

¿Cómo salir correctamente de una cadena de promesas?

Mantén la atención porque en este enunciado vas a hallar el arreglo que buscas.Este enunciado fue aprobado por nuestros especialistas para garantizar la calidad y exactitud de nuestro contenido.

Solución:

Suena como si quisieras rama, para no romper – desea continuar como de costumbre hasta el done. Una buena propiedad de las promesas es que no solo se encadenan, sino que también se pueden anidar y anidar sin restricciones. En su caso, puede colocar la parte de la cadena que desea “romper” dentro de su if-declaración:

Menus.getCantinas().then(function(cantinas) 
    Menus.cantinas = cantinas;

    if (cantinas.length == 0)
        return Menus; // break!

    // else
    return $.when(Menus.getMeals(cantinas), Menus.getSides(cantinas))
    .then(function(meals, sides) 
        Menus.sides = sides;
        Menus.meals = meals;
        return Menus.getAdditives(meals, sides);
    ).then(function(additives) 
        Menus.additives = additives;
        return Menus;
    );
).done(function(Menus) 
    // with no cantinas, or with everything
);

En primer lugar, creo que es mejor decir que está buscando “pasar por alto” (parte de) la cadena de promesas en lugar de “romperla”.

Como dices, probar “emptyResult” en varios lugares es bastante feo. Afortunadamente, hay disponible un mecanismo más elegante que se adhiere al mismo principio general de no ejecutar parte de la cadena de promesas.

Un mecanismo alternativo es usar el rechazo de la promesa para controlar el flujo, luego volver a detectar las condiciones de error específicas más adelante en la cadena y volver a colocarlo en la ruta del éxito.

Menus.getCantinas().then(function(cantinas) 
    Menus.cantinas = cantinas;
    if(cantinas.length == 0) 
        return $.Deferred().reject(errMessages.noCantinas);
     else 
        return $.when(Menus.getMeals(cantinas), Menus.getSides(cantinas));
    
).then(function(meals, sides) 
    Menus.sides = sides;
    Menus.meals = meals;
    return Menus.getAdditives(meals, sides);
).then(function(additives) 
    Menus.additives = additives;
    return Menus;
).then(null, function(err) 
    //This "catch" exists solely to detect the noCantinas condition 
    //and put the chain back on the success path.
    //Any genuine error will be propagated as such.
    //Note: you will probably want a bit of safety here as err may not be passed and may not be a string.
    return (err == errMessages.noCantinas) ? $.when(Menus) : err;
).done(function(Menus) 
    // with no cantinas, or with everything
);

var errMessages = 
    'noCantinas': 'no cantinas'
;

En el lado positivo, encuentro que la falta de anidamiento mejora la legibilidad de la ruta de éxito natural. Además, al menos para mí, este patrón requeriría un mínimo de malabares mentales para acomodar más desvíos, si es necesario.

En el lado negativo, este patrón es un poco menos eficiente que el de Bergi. Mientras que el camino principal tiene el mismo número de promesas que el de Bergi, el cantinas.length == 0 la ruta requiere uno más (o uno por desvío si se codificaron varios desvíos). Además, este patrón requiere una nueva detección confiable de condiciones de error específicas, por lo tanto, el errMessages objeto – que algunos pueden encontrar desmerece.

Para las personas que usan promesas integradas en el navegador y buscan una manera de detener la cadena de promesas sin que todos los consumidores sepan sobre el caso de rechazo, desencadenando cualquier encadenado then‘s o catches o tirar cualquier Uncaught (in promise) errores, puede usar lo siguiente:

var noopPromise = 
  then: () => noopPromise, 
  catch: () => noopPromise


function haltPromiseChain(promise) 
  promise.catch(noop)

  return noopPromise


// Use it thus:
var p = Promise.reject("some error")
p = haltPromiseChain(p)
p.catch(e => console.log(e)) // this never happens

Básicamente, noopPromise es una interfaz de promesa básica que acepta funciones de encadenamiento, pero nunca ejecuta ninguna. Esto se basa en el hecho de que, al parecer, el navegador usa el tipo de pato para determinar si algo es una promesa, por lo que YMMV (probé esto en Chrome 57.0.2987.98), pero si eso se convierte en un problema, probablemente podría crear una instancia de promesa real y neutralizar sus métodos then y catch.

Reseñas y calificaciones del post

Agradecemos que quieras añadir valor a nuestra información añadiendo tu veteranía en las ilustraciones.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *