2016-07-26 8 views
1

Ich habe eine Funktion, die Daten hat, die eine Kombination von Versprechen Daten und einfache mathematische Werte ist. Hier ist die Funktion:AngularJS: Funktion mit Versprechen und nicht versprechen Daten

_getTotalPrice = function() { 

      var price = 0; 
      // Simple Math data. 
      // Calculate price for channels first. 
      price = price + (num_channels - 5)*(4); 


      var themepacks = cart.themepacks; 
      if(themepacks) { 
       angular.forEach(themepacks, function(pack, index) { 

       // data coming from a service 
       channelFactory.getThemePack(pack).then(function(result) { 
        price = price + Number(result.packPriceAmt); 
        console.log("price", price); 
        }); 
       }); 
      } 

      console.log(" Total price", price); 
      return price; 
}; 

Zum Zeitpunkt der Seite zu laden, wird der Wert von Total price und price unterscheidet. Dies liegt daran, dass die price geladen wird, nachdem das Versprechen gelöst wurde. Wie kann ich warten, bis das Versprechen abgeschlossen ist, bevor der Wert zurückgegeben wird? Erstelle ich ein anderes Versprechen innerhalb dieser Funktion?

+1

Haben Sie einen Blick auf $ q hatte? Siehe http://www.codeducky.org/q-serial/ oder ein anderes Beispiel. – Naveen

+2

Sie können * nicht warten *, um einen Wert innerhalb der Funktion zurückzugeben. Es wird entweder mit "return" zurückgegeben oder "undefined" wird als implizite Rückgabe zurückgegeben. Gibt ein Versprechen zurück, das einen Wert zurückgibt. – estus

Antwort

1

Die Funktion muss selbst eine Zusage für den Gesamtpreis zurückgeben, die von allen (all) der Auflösungen des erstellten Versprechens abhängig ist.

Zuerst wird ein wenig Factoring klar helfen it up:

// return a promise for a theme pack price 
function priceOfPack(pack) { 
    return channelFactory.getThemePack(pack).then(function(result) { 
     return Number(result.packPriceAmt); 
    }); 
} 

Dies macht klarer die Idee, dass wir asynchron eine Reihe von Preisen sammeln fahren. Jetzt ist die Schleife einfacher ...

_getTotalPrice = function() { 
    var themepacks = cart.themepacks || []; 
    var promises = []; 
    angular.forEach(themepacks, function(pack, index) { 
     promises.push(priceOfPack(pack)); 
    }); 
    var basePrice = (num_channels - 5) * 4; 

    // when all promises are resolved, they will be with an array of prices 
    return $q.all(promises).then(function(result) { 
     return result.reduce((a, b) => { a + b }, basePrice); 
    }); 
} 

Der Anrufer muss erkennen, dass die neue Funktion ein Versprechen zurück, und dementsprechend ändern, so ...

_getTotalPrice().then(function(result) { 
    // result is the totalPrice 
}); 
+0

was ist mit 'if (! Themapacks)'? – charlietfl

+0

@charlietfl, ja, ich habe nicht die gesamte _getTotalPrice-Methode geliefert. Nur die Bits, die zu Versprechungen passen. – danh

+0

raten OP weiß nicht, sie brauchen ein anderes Versprechen für andere Bedingung zurückgegeben – charlietfl

1

Try this:

_getTotalPrice = function() { 

      var price = 0; 
      // Simple Math data. 
      // Calculate price for channels first. 
      price = price + (num_channels - 5)*(4); 


      var themepacks = cart.themepacks; 
      if(themepacks) { 
       angular.forEach(themepacks, function(pack, index) { 

       // data coming from a service 
       return channelFactory.getThemePack(pack).then(function(result) { 
        price = price + Number(result.packPriceAmt); 
        return $q.when(price); 
        }); 
       }); 
      } 
      else{ 
       return $q.when(price); 
      } 
}; 

_getTotalPrice().then(function(price){ 
    console.log(price); 
}); 

Es wird Asynchron-Funktion sein.

+0

Rückkehr innerhalb forEach tut nichts und Sie brauchen Array von Versprechen von dieser Schleife erstellt. Lösung wird nicht funktionieren – charlietfl

+0

oh, ich verpasst, dass er forEach so stattdessen u diese verwenden müssen: return $ q.all (Versprechen) .then (function (Ergebnisse) { angular.forEach (Ergebnisse, Funktion (Ergebnis) { Preis = Preis + Anzahl (result.packPriceAmt); }); Rückgabe $ q.when (Preis); }); – uamanager

+0

no point posting in comment ... nur update antwort – charlietfl