2016-07-02 3 views
0

Ich versuche zu lernen, Bluebird Versprechen zu verwenden, und ich bin ein bisschen verloren.Asyncronous Mapping über eine Sammlung mit einer Funktion, die ein Versprechen zurückgibt

Ich habe zwei Datenbanktabellen: topic und subject.

Die topic Tabelle hat eine subject_id Spalte, die dann verwendet werden kann, um die subject Tabelle für den Betreff Titel abzufragen.

Ich habe eine orm, die asynchron abfragt und eine Zusage zurückgibt.

letztlich von der topic Abfrage zurück aus den nachfolgenden subject Abfragen in dem jedes Element in der Anordnung der Objekte zunächst zurück Ich versuche, ein Modell Methode für Themen zu schreiben, die die Suche für Dich tun, Injizieren der subject_title.

Ich versuche Promise.map zu verwenden, aber das funktioniert nicht. Der folgende Code funktioniert nicht. Ich habe es nie erwartet, aber ich denke, es ist die Essenz dessen, was ich erreichen will.

var promise = orm.select({ 
    db:  db, 
    table: 'topic', 
    where: args.where, 
    order: args.order, 
    limit: args.limit, 
    offset: args.offset, 
    group: args.group 
}).map(function (topic) { 
    var promise = orm.select({ 
     db: db, 
     table: 'subject', 
     qrm: 'one', 
     where: {id: topic.subject_id} 
    }).then(function (subject) { 
     topic.subject_title = subject; 
    }); 
    return promise; 
}); 

return promise; 

Also, vorausgesetzt, dass ein Vanille topic Objekt hat die Eigenschaften:

[subject_id, title, description] 

Und ein subject Objekt hat:

[id, title] 

ich die obige Funktion soll ein Array von Objekten zurück mit folgenden Eigenschaften:

[subject_id, subject_title, title, description] 

Was ist der sauberste Weg, dies zu erreichen?

+0

Warum nicht Mutation vermeiden und ein neues Objekt mit Ihrer neuen Eigenschaft zurückgeben? – elclanrs

+1

Was gibt 'orm.select()' zurück? Gibt es ein Bluebird-Versprechen? Und was sind die erfüllten Daten? – jfriend00

+0

@ jfriend00 Es gibt ein Bluebird-Versprechen. Die fulfillierten Daten sind eine Anordnung von Objekten. Jedes Objekt im Array repräsentiert eine Zeile in der 'topics' Tabelle. – LukeP

Antwort

1

Es scheint, dass Sie nur das modifizierte topic Objekt von Ihren .then() Handler müssen zurückkehren, damit er den erfüllte Wert bleibt:

return orm.select({ 
    db:  db, 
    table: 'topic', 
    where: args.where, 
    order: args.order, 
    limit: args.limit, 
    offset: args.offset, 
    group: args.group 
}).map(function (topic) { 
    return orm.select({ 
     db: db, 
     table: 'subject', 
     qrm: 'one', 
     where: {id: topic.subject_id} 
    }).then(function (subject) { 
     topic.subject_title = subject; 
     // Add return here so topic stays the fulfilled value 
     return topic; 
    }); 
}); 

Der fullfilled Wert der Top-Level-Versprechen sollte ein Array von modifizierten Thema Objekten sein .

+0

oh! Du hast Recht, das funktioniert. Ich ging davon aus, dass ich mit einer Reihe von Versprechen statt einer Reihe von Ergebnissen enden würde. Wie kann die "map" -Funktion darauf warten, dass alle Versprechen erfüllt werden, bis sie sich selbst erfüllt haben? – LukeP

+0

@LukeP - Das ist es, was '.map()' auf einem Bluebird-Versprechen tut. Es ist nur eine Abkürzung, um ein Array von Versprechungen zu sammeln, indem man ein Array iteriert und dann 'Promise.all()' aufruft, das offensichtlich auf alle Versprechen wartet, die man ihm gibt, bevor man sein Master-Versprechen löst. Das [bluebird doc für '.map()'] (http://bluebirdjs.com/docs/api/promise.map.html) erklärt das ziemlich gut. – jfriend00