Я использую класс ES6 для объединения некоторых функций вместе в узле. Вот (в основном), как это выглядит:Методы ES6 получают нулевое значение «this» и переменные класса недоступны
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;
Я думал, что с классами ES6, как назначить общественные переменные были просто ссылаться this
и способ для инициализации этих переменных с помощью конструктора, как именно он показывает в моем определении класса.
Вот как я звоню класс (в отдельном файле):
var Processor = require('./processDocs');
var pr = new Processor(id);
var docs;
pr.process();
Вот вопрос, когда я console.log
из this
из конструктора, я получаю мое { id: id }
значение как предсказывал; однако, всякий раз, когда я выхожу из this
в getDocs
, когда process
запущен, он равен нулю. НО, когда я выхожу из this
в process()
прямо перед водопадом, я получаю свой первоначальный объект.
Есть ли причина для этого?
Btw, я использую узел: v0.10.33
и babel-node 4.6.6
, и я запускаю babel-узел с флагом --harmony
. Прежде чем кто-нибудь спросит, я не могу обновить версию более нового узла из-за большой зависимости, которая застряла на v0.10.x
.
EDIT Мне удалось создать обходное решение, но оно не очень похоже на es6. Проблема, похоже, связана с async.waterfall
. Я должен был использовать .bind
исправить:
async.waterfall([
this.getDocs.bind(this),
this.alterDocs.bind(this),
this.reindexSearch.bind(this)
]);
Я не понимаю, что вы имеете в виду под «не очень ES6 типа»? Методы не были, не являются и не будут связаны с экземпляром сами по себе. Кстати, если вы хотите настоящий код ES6, а затем отмените 'async' и используйте обещания. – Bergi
Я говорю не очень 'es6-like', потому что мне пришлось использовать' .bind (this) ', когда мне не нужно. Так вы говорите, что если я вызову метод из класса, 'this' будет потерян? Потому что это не имеет смысла для меня. Когда я использовал 'pr.process()', 'this' был прав, и когда я вызывал' this.getDocs' непосредственно из 'this.process()', он также сохранил свой 'this'. Кажется, это проблема 'async'. Кроме того, если бы я хотел быть очень похожим на ES6, я бы использовал генераторы :) Обещания - это ES5 и все равно будут приводить к обратному ад, который я пытаюсь предотвратить, используя 'async'. – antjanus
Почему, по-вашему, вам не нужно использовать '.bind()'? Ваши передающие ссылки на функцию в другом месте. Вы не вызываете их * из своего класса! Посылы - это правильное решение здесь (они очень много ES6! Генераторы - это не асинхронная функция!): 'Process() {return this.getDocs(). Then (docs => this.alterDocs (docs)), затем (alteredDocs => his.redindexSearch (измененныйDocs)); } ' – Bergi