【发布时间】:2019-07-18 09:31:21
【问题描述】:
我有一个传感器类和一个扩展它的类。两个类的构造函数都使用异步操作。
基类:
/**
* Basic sensor class
*/
class Sensor {
/**
* Constructor function
* @param {object} options - sensor options
* @param {*} callback - fn(err)
*/
constructor(options, callback) {
...
callback(null);
版本 A(失败): 扩展类,在 super 的回调中调用:
ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
/**
* Mock of the Chirp water level sensor.
*/
class ChirpSensorMock extends SensorMock {
/**
* Constructor function
* @param {object} options - sensor options
* @param {*} callback - fn(err)
*/
constructor(options, callback) {
super(options, (err) => {
if (err) { return callback(err); }
async.eachSeries(this.detectors,
版本 B(有效,但给出 eslint 错误):
Missed superclass's construction invocation
constructor(options, callback) {
async.series([
(next) => super(options, next),
(next) => {
async.eachSeries(this.detectors,
有没有办法使用回调(并避免async/await)调用super 并在回调中使用this?或者我应该忽略 eslint 错误,例如// eslint-disable-next-line constructor-super
【问题讨论】:
-
"两个类的构造函数都使用异步操作。"这是一个反模式。你可以说实现一些
init在创建实例后调用的方法,或者在创建实例之前执行异步操作的工厂方法。 -
当实例已经初始化时,您需要确保始终异步调用回调。但正如 Yury 所说,实际问题是doing asynchronous things in a constructor(甚至是回调)。
-
@Bergi 我理解链接中的讨论。我仍然不确定在我的情况下这是否有意义。传感器需要异步启动。我已经在类方法中进行了异步启动。我可以在
new之后调用 boot,但到那时我的传感器仍然无法使用。分离 boot fn 也没有多大意义恕我直言,因为它利用了类的方法。 -
@AndiGiga 如何在实例尚不可用时利用类的方法?如果您认为那些是“内部方法”,不必对实例是否“外部可用”做任何事情,也许您应该拆分实现。否则,是的,在创建实例之后、在使用它之前调用
await instance.boot()是一个合理的解决方案。 (不仅仅是在构造函数中做异步的东西)。
标签: javascript node.js eslint super superclass