我做了一个类服务。我尝试每X秒运行一次间隔。默认值为30秒。但如果其他类需要,我想设置一个自定义延迟。我找不到覆盖父类中变量的方法。
class Service {
delay = 30;
constructor(api, client = undefined) {
this.api = api;
this.client = client;
this.handle();
}
getMiliSeconds() {
return this.delay * 1000;
}
service = async () => {
// Service to run in background
}
handle() {
setInterval(() => { this.service() }, this.getMiliSeconds());
}
}
module.exports = Service;
当我扩展类服务时,我试图覆盖delay
变量
class Notification extends Service {
delay = 60;
service = async () => {
// I am not running every 60 seconds.
}
}
module.exports.Notification = Notification;
但是,间隔函数仍然每30秒运行一次。而不是我在Notifications类中设置的60秒。
问题是超级构造函数在子构造函数运行或分配给实例之前运行。例如:
class Parent {
prop = 'foo'
constructor() {
console.log(this.prop);
}
}
class Child extends Parent {
prop = 'bar'
}
将始终记录foo
,因为类字段prop = 'bar'
只有在父构造函数完成并且控制流返回给子构造函数之后才会运行。
当您在超级构造函数中调用this.handle
时,getMiliSeconds
会立即运行,在子级有机会将自己的delay
分配给实例之前检索延迟。
为了解决这个问题,我将this.handle
从构造函数中移出,这样它就可以在对象完全实例化后(而不是之前(按需调用。
在下面的代码段中,子类中的delay = 1
现在成功地使子服务每秒运行一次,而不是每3秒运行一次。
class Service {
delay = 3;
constructor(api, client = undefined) {
this.api = api;
this.client = client;
}
getMiliSeconds() {
return this.delay * 1000;
}
service = async () => {
console.log('parent service');
// Service to run in background
}
handle() {
setInterval(() => { this.service() }, this.getMiliSeconds());
}
}
class Notification extends Service {
delay = 1;
service = async () => {
console.log('child service');
}
}
const n = new Notification();
n.handle();
另一种方法是将delay
属性放在原型上,而不是作为类字段(这相当于构造函数内部,而允许相对构造函数运行的时间是问题所在(:
class Service {
constructor(api, client = undefined) {
this.api = api;
this.client = client;
this.handle();
}
getMiliSeconds() {
return this.delay * 1000;
}
service = async () => {
console.log('parent service');
// Service to run in background
}
handle() {
setInterval(() => { this.service() }, this.getMiliSeconds());
}
}
Service.prototype.delay = 3;
class Notification extends Service {
service = async () => {
console.log('child service');
}
}
Notification.prototype.delay = 1;
const n = new Notification();