2017-09-07 3 views
0

Comment rejeter la promesse de la boucle _.each, il n'atteint jamais document.write('Failed');. Y at-il de meilleures fonctions dans lodash pour gérer cette situation.Comment rejeter la promesse dans la boucle _.each

function check(){ 
    return Promise 
     .all(
    [ 
     Promise.resolve([1,3,4]), 
     Promise.resolve([0,4,3]), 
     Promise.resolve(undefined) 
    ]).then(function(results){ 
     return _.each(results, function(result){ 
     return _.each(result, function(value) { 
      // should reject when value is 0 
      if(!value){ 
      return Promise.reject(); 
     } 
     }); 
     }); 

    }); 
    } 

check().then(function(){ 
    document.write('All Success'); 
    }, function(){ 
    // Never reaching this code.. :(
    document.write('Failed'); 
    }); 

Voici le plnkr.co link

+0

Vous revenez du rappel 'each', pas du rappel' then'. Utilisez une boucle appropriée au lieu de lodash! – Bergi

Répondre

2

Il n'y a aucune raison de créer une nouvelle promesse dans la then rappel et rends le. Le but des promesses est de vous permettre d'écrire du code asynchrone de manière plus «synchrone». Qu'est-ce que vous voulez faire dans votre rappel then est de lancer une erreur:

function check(){ 
    return Promise 
     .all(
    [ 
     Promise.resolve([1,3,4]), 
     Promise.resolve([0,4,3]), 
     Promise.resolve(undefined) 
    ]).then(function(results){ 
     return _.each(results, function(result){ 
     return _.each(result, function(value) { 
      // should reject when value is 0 
      if(!value){ 
      throw new Error(); 
     } 
     }); 
     }); 

    }); 
    } 

check().then(function(){ 
    document.write('All Success'); 
    }, function(){ 
    // Never reaching this code.. :(
    document.write('Failed'); 
    }); 

Cela entraînera un rejet dans la chaîne de promesse.

2

La fonction retourne _.each() la liste dans le premier paramètre et ne peut être rompu sur, selon le documentation.

Pour obtenir ce que vous voulez, essayez d'utiliser la boucle for...of comme indiqué here:

function check(){ 
    return Promise 
     .all(
    [ 
     Promise.resolve([1,3,4]), 
     Promise.resolve([0,4,3]), 
     Promise.resolve(undefined) 
    ]).then(function(results){ 
     for (let result of results) { 
     for (let value of result) { 
      // should reject when value is 0 
      if(!value){ 
      return Promise.reject(); 
     } 
     }); 
     }); 

    }); 
    } 

check().then(function(){ 
    document.write('All Success'); 
    }, function(){ 
    // Never reaching this code.. :(
    document.write('Failed'); 
    }); 

Si vous insistez sur l'utilisation de la boucle _.each() vous ne serez jamais en mesure de sortir de la boucle quand il frappe le premier rejet, donc je ne recommanderais pas cette approche. Cependant, vous pouvez déclarer une variable juste avant la première boucle qui contient initialement une promesse résolue, la remplacer par une promesse rejetée si la vérification !value passe, puis renvoyer cette variable après la boucle à la fin de la finale then().

+0

Vous cherchez une approche basée sur lodash pour cette situation. Comme les données, je traite avec peu de complexité. – bash

2

Vous pouvez utiliser Promise.all à nouveau, combiné avec flatten et map

function check(){ 
 
    return Promise 
 
    .all(
 
    [ 
 
     Promise.resolve([1,3,4]), 
 
     Promise.resolve([0,4,3]), 
 
     Promise.resolve(undefined) 
 
    ]).then(function(results){ 
 
     return Promise.all(_(results).flatten().map(result => { 
 
     if(result === 0) return Promise.reject() 
 
     })) 
 
     
 
    }); 
 
} 
 

 
check().then(function(){ 
 
    document.write('All Success'); 
 
    //lert("all success"); 
 
    }, function(){ 
 
    document.write('Failed'); 
 
    })
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.2/lodash.js"></script>

vous pouvez également utiliser some

function(results){ 
    return Promise.all(results.map(result => { 
    if([].concat(result).some(value => value === 0)) { 
     return Promise.reject() 
    } 
} 
+0

que se passe-t-il si le résultat est un objet? Dans l'exemple 'Promise.resolve ([1,3,4])', que se passe-t-il s'il s'agit de 'Promise.resolve ([{}, {}, {} ]) '. – bash

+0

@bash Comment voulez-vous comparer les objets à 0? –

+0

Ma logique avec dans la fonction est peu complexe et les critères de rejet sont différents. vous avez proposé 2 solutions 'Promise.all (_ (results) .flatten(). map (result' et' [] .concat (result) .some'. vont-elles appliquer les objets? – bash