2015-08-16 12 views
5

Ich arbeite an einem Versprechen-Projekt in Node.js mit bluebird, und ein anderes in native Versprechen von ES6. In den beiden habe ich eine Kette, wo ich eine Datenbank in das folgende Formular abfragen:Funktion gelten mit Promises

some_function(/*...*/) 

    .then(function() { 
     return query("SELECT `whatever` FROM `wherever` ") 
    }) 

    .then(/*...*/) 

Beachten Sie, dass query offensichtlich ein Versprechen an das Abfrageergebnis aufgelöst zurückgibt. Dies wiederholt sich in mehreren Ketten, und ich suche nach einer Möglichkeit, den unbenutzten Funktions-Wrapper aufzuräumen.

ich Function.prototype.apply() natürlich verwenden würde, aber in diesem Fall, wenn ich versuche:

.then(query.apply(this, ["SELECT * FROM ... "])) 
.then(function(rows){ /*...*/ }) 

Die nächste Funktion in der Kette wird rows als undefined.

Danke von voraus. Deine Hilfe wird geschätzt.

+0

Sie wollen wahrscheinlich [Function.prototype.bind()] (https: // developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) anstelle von apply: '.then (query.bind (query," SELECT * FROM ... "))'. Sie können .bind() verwenden, um eine neue Funktion basierend auf 'query' mit Ihrer SQL-Zeichenfolge [partially applied] (https://en.wikipedia.org/wiki/Partial_application) zu erstellen. –

+0

'apply' * ruft * die Methode auf (sie gibt keine teilweise angewendete Funktion zurück), also übergibt man die Abfragefunktion nicht an' then', sondern den Rückgabewert davon. – doldt

+0

Warte, ist das 'zurück query.apply (" SELECT ... ")' oder 'return query (" SELECT ... ")'? Im ersten Fall haben Sie eine '.apply' Methode, die * nicht * der' Function.prototype' ist. Verwechsle sie nicht. – Bergi

Antwort

4

Sie haben eine Funktion Verweis auf .then() übergeben, damit Ihre Entscheidungen sind wie folgt:

  1. Verwenden Sie eine Inline-anonyme Funktion, wie Sie sind.
  2. Erstellen Sie Ihre eigene Dienstprogrammfunktion, die eine andere Funktion zurückgibt (siehe Beispiel unten)
  3. Verwenden Sie .bind(), um eine andere Funktion zu erstellen.

Die Inline-anonyme

some_function(/*...*/).then(function() { 
    return query.apply("SELECT `whatever` FROM `wherever` ") 
}).then(/*...*/) 

Ihre eigene Funktion Wrapper

function queryWrap(q) { 
    return function() { 
     return query.apply(q); 
    } 
} 

some_function(/*...*/) 
    .then(queryWrap("SELECT `whatever` FROM `wherever` ")) 
    .then(/*...*/) 

Dieser Wrapper könnte nützlich sein, wenn Sie es an mehreren Stellen verwenden könnte. Wahrscheinlich nicht wert für nur eine Invokation.

Verwenden .bind()

some_function(/*...*/) 
    .then(query.apply.bind(query, "SELECT `whatever` FROM `wherever` ")) 
    .then(/*...*/) 
+0

Im letzten Beispiel mit 'bind()', warum haben Sie 'query.apply.bind (/*...*/)' '? Sollte es nicht 'query.bind (/*...*/)' sein? Danke für die Antwort. :) – Selfish

3

In es6, lösen Pfeil Funktionen dies am besten:

.then(() => query.apply("SELECT `whatever` FROM `wherever` ")) 
.then(rows => { /*...*/ }) 
+0

Hey, nette Lösung aber löst nur einen der genannten Fälle. Danke! – Selfish