2017-08-31 5 views
2

Ich habe viele sehr ähnliche Fragen gesehen, aber keine direkte Antwort für das tatsächliche Warten geben. Ich habe ein Skript basierend auf Bookshelf.js;Node.js Warten auf Rückruf oder Datenbank Antwort

var Product = bookshelf.Model.extend({ 
    tableName: 'amazon_products', 
    hasTimestamps: true, 
    virtuals: { //https://github.com/bookshelf/bookshelf/wiki/Plugin:-Virtuals 
    hasSiteProduct: function() { 
     var product_references = this.related('siteProductsReferences').fetch() 
     return product_references.length; 
    } 
    } 

}); 

Ich habe Setup eine virtuelle Eigenschaft, die einfach die OneToMany Beziehungen des Modells zählen und den Zählwert zurück. Aber in diesem Fall sieht es so aus, als ob this.related('siteProductsReferences').fetch() einige Zeit dauern muss, bevor eine Antwort zurückgegeben wird. Die this.related('siteProductsReferences').fetch() hat auch ein Versprechen, das so aussehen kann;

this.related('siteProductsReferences').fetch().then(function(result) { 
    // ... 
}); 

Ich baue dies um über eine API zurückgegeben werden. Wenn ich einfach return this.related('siteProductsReferences').fetch() zu der Methode hinzufüge, bekomme ich eine volle l bekommen;

,"hasSiteProduct":{"isFulfilled":false,"isRejected":false} 

So klar ist der Rückruf nicht beendet.

+0

Wahrscheinlich ein Duplikat von [Wie gebe ich Antwort von einem asynchronen Aufruf zurück] (https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call). – jfriend00

+1

'this.related ('siteProductsReferences'). Fetch()' gibt scheinbar ein Versprechen zurück. Sie verwenden '.then()' in einem Versprechen, einen Rückruf zu registrieren, der aufgerufen wird, wenn er einen Wert hat. – jfriend00

+0

Mögliches Duplikat von [Wie gebe ich die Antwort von einem asynchronen Anruf zurück?] (Https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – peteb

Antwort

2

Da die Datenbankoperation eine Zusage zurückgibt, muss Ihre Funktion auch eine Zusage zurückgeben - es gibt keinen Ausweg, Sie müssen die Zusage an den Aufrufer weitergeben, der .then() benötigt.

Below funktioniert nicht, weil Sie nicht .length auf ein Versprechen zugreifen können, die bisher noch nicht erfüllt hat:

hasSiteProduct: function() { 
    var product_references = this.related('siteProductsReferences').fetch() 
    return product_references.length; 
} 

aber Sie können dies tun:

hasSiteProduct: function() { 
    var product_references_length_promise = 
    this.related('siteProductsReferences').fetch() 
    .then(product_references => { 
     return product_references.length; 
    }) 

    // return the promise - it has not completed yet, client must .then() it 
    return product_references_length_promise; 
} 

der Kunde muss .then() das Versprechen zurückgegeben wie folgt:

hasSiteProduct().then(num_product_references => { 
    // do something with num_product_references 
}) 

Für was es wert ist, denke ich, dass Sie möglicherweise die falscher Pfad beim Erstellen eines In-Memory-Modells Ihrer Daten. Dies ist eine Technik, die von objektorientierten Entwicklern bevorzugt wird, wenn es um Daten aus einer Datenbank geht, aber ich habe es immer sehr schwer gefunden, dies auf eine elegante Art und Weise zu machen - es braucht viel Aufwand, um das Modell zu erstellen und der Aufwand funktioniert nicht. t lohnt sich wirklich.

+0

Danke, das war die Erklärung, nach der ich gesucht habe. – LogicDev