Sto utilizzando una classe ES6 per raggruppare alcune funzionalità insieme nel nodo. Ecco (in pratica) che cosa assomiglia:I metodi ES6 ottengono null "questo" e le variabili di classe non sono accessibili
class processDocs {
constructor(id) {
this.id = id;
// console.log(this) returns { id: id }
}
getDocs(cb) {
// console.log(this) returns null
docs
.query(qb => {
qb.where('id', this.id);
})
.fetch()
.then(function(documents) {
cb(null, documents);
})
;
}
alterDocs(documents, cb) {
//some logic
}
reindexSearch(cb) {
//some logic
}
process() {
// console.log(this) returns { id: id }
async.waterfall([
this.getDocs,
this.alterDocs,
this.reindexSearch
]);
}
}
export default processDocs;
ho pensato che con le classi ES6, il modo di assegnare variabili pubbliche è stato quello di semplice riferimento this
e il modo per inizializzare le variabili tramite un costruttore è esattamente come si presenta nella mia definizione di classe.
Ecco come sto chiamando la classe (in un file separato):
var Processor = require('./processDocs');
var pr = new Processor(id);
var docs;
pr.process();
Ecco il problema, quando ho console.log
fuori this
dal costruttore, ottengo il mio valore { id: id }
come previsto; tuttavia, ogni volta che logout this
in getDocs
quando process
è in esecuzione, è null. MA, quando registro this
in process()
proprio prima della cascata, ottengo il mio oggetto originale.
C'è qualche motivo per questo?
Btw, sto usando il nodo: v0.10.33
e il nodo babel 4.6.6
ed eseguo babel-node con il flag --harmony
. Prima che qualcuno chieda, non posso aggiornare a una versione più recente del nodo a causa di una dipendenza importante che è bloccata a v0.10.x
.
EDIT Sono stato in grado di creare una soluzione alternativa, ma non è molto simile a ES6. Il problema sembra essere con async.waterfall
. Ho dovuto usare un .bind
per risolvere il problema:
async.waterfall([
this.getDocs.bind(this),
this.alterDocs.bind(this),
this.reindexSearch.bind(this)
]);
Non capisco cosa si intende per "non molto ES6-like"? I metodi non erano, non lo sono e non saranno vincolati all'istanza da soli. A proposito, se si desidera un vero codice ES6, quindi rottamare 'async' e usare le promesse. – Bergi
Sto dicendo che non è molto "es6-like" perché dovevo usare '.bind (this)' quando non dovevo. Quindi stai dicendo che se invoco un metodo all'interno di una classe, 'this' andrà perso? Perché non ha senso per me. Quando ho usato 'pr.process()', 'this' era corretto e quando ho richiamato' this.getDocs' direttamente da 'this.process()', ha mantenuto anche il suo 'this'. Questo sembra essere un problema 'async'. Inoltre, se volessi essere molto simile ad ES6, userei i generatori :) Le promesse sono ES5 e causerebbero comunque un inferno di callback che è quello che sto cercando di prevenire usando 'async'. – antjanus
Perché pensi di non aver bisogno di usare '.bind()'? I tuoi riferimenti di passaggio per funzionare altrove. Tu * non li stai invocando * dalla tua classe! Le promesse sono la soluzione giusta qui (sono molto ES6! I generatori non sono una funzione asincrona!): 'Process() {return this.getDocs(). Then (docs => this.alterDocs (docs)). Then (alteredDocs => his.redindexSearch (alteredDocs)); } ' – Bergi