2015-08-16 18 views
5

Sto lavorando a un progetto basato su promesse in Node.js utilizzando bluebird e un altro in promesse native di ES6. In entrambi, ho una catena in cui ho interrogare un database nel seguente formato:La funzione si applica con Promises

some_function(/*...*/) 

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

    .then(/*...*/) 

noti che query ritorna, ovviamente, una promessa deliberato di risultato della query. Questo si ripete in diverse catene, e sto cercando un modo per ripulire il wrapper della funzione inutilizzato.

mi piacerebbe naturalmente uso Function.prototype.apply(), ma in questo caso, quando provo:

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

La funzione successiva nella catena ottiene rows come undefined.

Grazie da domani. Il tuo aiuto è apprezzato.

+0

probabilmente avrete bisogno [Function.prototype.bind()] (https: // developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) invece di applicare: '.then (query.bind (query," SELECT * FROM ... "))'. Puoi usare .bind() per creare una nuova funzione basata su 'query' con la tua stringa SQL [parzialmente applicata] (https://en.wikipedia.org/wiki/Partial_application). –

+0

'apply' * chiama * il metodo (non restituisce una funzione parzialmente applicata), quindi non si passa la funzione di query a' then', ma il valore di ritorno di esso. – doldt

+0

Aspetta, è quel 'return query.apply (" SELECT ... ")' o 'return query (" SELECT ... ")'? Nel primo caso, si ha un metodo '.apply' che * non * è quello' Function.prototype'. Non mescolarli. – Bergi

risposta

4

devi passare una funzione di riferimento per .then() in modo che le scelte sono le seguenti:

  1. Usa una funzione anonima come sei in linea.
  2. Creare la propria funzione di utilità che restituisce un'altra funzione (vedere esempio di seguito)
  3. Utilizzare .bind() per creare un'altra funzione.

La linea anonima

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

La funzione proprio involucro

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

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

Questo wrapper potrebbe essere utile se si potesse utilizzare in più posizioni. Probabilmente non ne vale la pena per una sola invocazione.

Usa .bind()

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

Nell'ultimo esempio con 'bind()', perché hai usato 'query.apply.bind (/*...*/)'? Non dovrebbe essere 'query.bind (/*...*/)'? Grazie per la risposta però. :) – Selfish

3

In ES6, funzioni di direzione risolvere questo migliore:

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

Ehi, bella soluzione, ma risolve solo uno dei casi citati. Grazie! – Selfish