2016-09-21 3 views
1

Dies ist im Grunde mein Code, mit q:Aufruf Versprechen in einem anderen Versprechen, bedingt

let d = Q.defer(); 
let result = { 
    name: 'peter' 
}; 

d.resolve(result); 
return d.promise; 

aber ich muss jetzt einen Schritt ausführen auf einer bestimmten Bedingung basiert. Dieser Schritt ruft ein anderes Objekt auf, das ebenfalls eine Zusage zurückgibt. Ich habe also Versprechungen verschachtelt, wenn das der richtige Ausdruck ist.

Etwas wie folgt aus:

let d = Q.defer(); 
let result = { 
    name: 'peter' 
}; 

if (someParameter) { 
    otherService.getValue() // Let's say it returns 'mary' 
     .then((res) => { 
      result.name = res; 
     }); 
} 

d.resolve(result); 
return d.promise; 

Dies jedoch nicht funktioniert (die name Eigenschaft ist immer noch 'Peter'). Wahrscheinlich aufgrund der Tatsache, dass mein inneres Versprechen zu einem späteren Zeitpunkt gelöst wird?

Ich habe das auch versucht, aber es funktioniert nicht, wenn ich den anderenService, der ein Versprechen zurückgibt, aufrufen. Es funktioniert, wenn ich den Wert gerade eingestellt:

let d = Q.defer(); 
let result = { 
    name: 'peter' 
}; 

d.resolve(result); 
return d.promise 
    .then((data) => { 
     if (someParameter) { 
      // Works 
      data.name = 'john'; 

      // Doesn't work 
      otherService.getValue() 
       .then((res) => { 
        data.name = res; 
       }); 
     } 

     return data; 
    }); 

Hier wird der Name ‚John‘, nicht ‚Mary‘ sein.

Klar bin ich Versprechungen verkennen, aber ich kann nicht meinen Kopf darum wickeln.

+0

Werfen Sie einen Blick auf [if-else-Fluss in Versprechen] (http://stackoverflow.com/q/26599798/1048572) – Bergi

Antwort

1

Kontrollfluss mit Versprechen ist ... Spaß?

Wie auch immer, Sie sind fast da, Sie können eine Promise in eine Promise einbetten sowie sie verketten. wenn man sie jedoch einbetten, müssen Sie die eingebettete Promise Kette return:

let d = Q.defer(); 
let result = { 
    name: 'peter' 
}; 

d.resolve(result); 
return d.promise 
    .then((data) => { 
     if (someParameter) { 

      // Should work now that we return the Promise 
      return otherService.getValue() 
       .then((res) => { 
        data.name = res; 
        // And we have to return the data here as well 
        return data; 
       }); 
     } 

     return data; 
    }); 

Promiseresolve Wert oder einen anderen Promise nehmen kann, und es wird den Fluss behandeln. Also, wenn wir return innerhalb einer then, kann der Wert, den wir zurückgeben kann ein anderer Promise oder nur ein Wert sein. Die Maschine wird sich um das Auspacken kümmern.

+0

Ihre Code funktioniert, ist aber so kompliziert, dass ich es für nicht sinnvoll halte. – Bergi

+0

@Bergi Entschuldigung, Sie fühlen sich so. Ich habe das OP einfach kopiert, um den Autor nicht weiter zu verwirren. der Code könnte viel ausdrucksvoller sein, ja. Da es sich bei der Post um Promise-Kontrollfluss handelt, ist es notwendig, ein vollständiges Beispiel zu zeigen. Es schien mir, dass der Autor über eingebettete Versprechen etc. verwirrt war. –

+0

Es ist kompliziert, aber inzwischen habe ich es umgestaltet. Außerdem ist mein Beispiel hier im Vergleich zu dem, was wir in unserem echten Code haben, trivial. Aber diese Antwort erklärte mir, was ich falsch mache. – Peter

2

Verwendung von Deferreds ist veraltet. Wenn überhaupt, sollten Sie den Q.Promise Konstruktor verwenden, aber Sie brauchen nicht einmal das. Verwenden Sie einfach die Q function, um ein Versprechen zu erstellen, das mit Ihrem Wert erfüllt wird.

Jetzt können Sie (und sollte) vereinfachen Ihren Code

let d = someParameter ? otherService.getValue() : Q('peter'); 
return d.then(res => ({ 
    name: res 
})); 
Verwandte Themen