2015-05-14 11 views
5

Ho la seguente chiamata q.all per risolvere due promesse. Ho controllato tutti i post ed ho provato tutti gli altri modi di attuazione q.all e il suo stesso casoq.tutto non funziona per più promesse

var xyzdeffered = $q.defer(); 
service1.getServiceDetail1($routeParams.id).then(function(promise) { 
    xyzdeffered.resolve(promise); 
}); 

var abcdeffered = $q.defer(); 
service2.getServiceDetail2($routeParams.id).then(function(promise) { 
abcdeffered.resolve(promise); 
}); 


$q.all([ xyzdeffered, abcdeffered ]).then(function(data) { 

    $scope.variable = data; 

}); 

mi aspetto la variabile in q.all dovrebbe ottenere popolata solo dopo le prime due promesse sono risolti. Ma sfortunatamente la chiamata al servizio stesso non viene restituita con i dati e il controllo passa al q.all. Trovo strano questo perché, come da documentazione, q.all è chiamato solo quando le tue promesse vengono restituite con 200 risposte e sono risolte. Ho controllato l'analisi delle chiamate di rete e ho anche messo un po 'di avviso per vedere la sequenza del codice e scoprire che l'allarme q.all è il primo avviso a essere spuntato e quindi le altre promesse sono state risolte. Mi fa davvero impazzire il motivo per cui una semplice implementazione di q.all non funziona .. Qualsiasi aiuto sarà apprezzato.

+1

Btw si sentiva in anti-modello più comune: 'service1.getServiceDetail1 ($ routeParams.id)' è già * * una promessa, perchè è necessario utilizzare '$ q.defer' a tutti? Metti semplicemente queste promesse nel tuo '$ q.all' – floribon

+0

Sì, corretto questi sono codificati da qualcun altro .. volevo usare il modello esistente ... ma voi ragazzi avete già confermato che l'implementazione è sbagliata –

risposta

8

Perché non chiamare direttamente $ q.all sulla prima promessa?

$q.all([ 
    service1.getServiceDetail1($routeParams.id), 
    service2.getServiceDetail2($routeParams.id) 
]).then(function(data) { 
    //Array of result [resultOfgetServiceDetails1, resultOfgetServiceDetails2] 
    $scope.variable = data; 
}); 
+0

Grazie per la conferma Kevin .. ho pensato di usarlo prima ..ma come il codice è stato scritto da qualcun altro .. semplicemente non volevo cambiare l'implementazione e usare un po 'di lavoro ... –

6

È necessario fare riferimento alla promessa sull'oggetto $q.defer() ritorno:

$q.all([ xyzdeffered.promise, abcdeffered.promise ]) 
+1

Questo è corretto. In qualche modo non correlato, raccomando vivamente di mettere le chiamate differite in un servizio che restituisce una promessa: ti dà una base di codice più pulita e più riutilizzabile. – AaronB

3

Per esempio si dispone di eseguire più query SQ-lite in modo sincrono solo passare la matrice di query (si può passare nulla) come args nella chiamata di questo metodo.

function methodThatChainsPromises(args,tx) { 

    var deferred = $q.defer(); 

    var chain = args.map(function(arg) { 

     var innerDeferred = $q.defer(); 

     tx.executeSql(arg,[], function(){  
      console.log("Success Query"); 
      innerDeferred.resolve(true); 
     }, function(){ 
      console.log("Error Query"); 
      innerDeferred.reject(); 
     }); 

     return innerDeferred.promise; 
    }); 

    $q.all(chain).then(
     function(results) { 
      deferred.resolve(true) 
      console.log("deffered resollve"+JSON.stringify(results)); 
     }, function(errors) { 
       deferred.reject(errors); 
       console.log("deffered rejected"); 
      }); 
      return deferred.promise; 
     } 
Problemi correlati