我的一般问题是我可以使用哪些技术来确保在Javascript中清理/释放资源?目前,我正在采用C(不使用goto)方法来查找函数中返回或异常的每个执行路径,并确保进行清理。
我的具体示例如下:在Node.js中我在对象成员函数中使用互斥(通过文件锁)(我需要互斥,因为我运行Node.js应用程序的多个实例,并且当不同实例与之交互时具有竞争条件文件系统)。
例如,在C ++中我会做类似以下的事情:
void MyClass::dangerous(void) {
MyLock lock(&this->mutex);
...
// at the end of this function, lock will be destructed and release this->mutex.
}
据我所知,JavaScript不提供任何RAII功能。在C中,我会使用goto
s在发生错误时展开我的资源分配,这样我只有一个函数的返回路径。
在Javascript中实现类似效果的一些技巧是什么?
使用在作用域末端调用的回调列表。需要时全部打电话给他们。
例如,使用此方法来解除附加到浏览器窗口的附加处理程序的初始化。包含去初始化代码的回调存储在列表中,该列表在窗口的卸载事件中处理。
不幸的是,由于异常安全要求,这种方法大多不适合范围管理。
您可以使用闭包和try ... finally
块来讨论RAII,如下所述:http://jeanlauliac.com/raii-in-javascript/
例如,
function using(start, close, execute) {
try {
start.call(this);
return execute.call(this);
} finally {
close.call(this);
}
}
// specialize to some resource (inside a Context2D wrapper)
usingScaledLineWidth(execute) {
const tmp = this.context.lineWidth;
const start = () => {
this.context.lineWidth *= Math.abs(this.cf().a);
};
const close = () => {
this.context.lineWidth = tmp;
};
return using.call(this, start, close, execute);
}
// later RAII based usage
stroke() {
// have to manually do this because we're not scaling context
if (this.context.strokeStyle !== "rgba(0, 0, 0, 0)") {
this.usingScaledLineWidth(()=>{
this.context.stroke();
});
}
}
不幸的是,它没有语言陈述(如析构函数和威慑破坏)。你必须使用qazxsw poi语句。
如果您想知道如何以类似于C ++的方式完成它,请在我尝试使用raii容器和TypeScript装饰器时查看try { ... } finally { ... }
。但我不确定它对生产代码有好处,因为其他开发人员可能会对这种方法感到困惑。
如果我们谈论TypeScript,我认为它可以由https://github.com/cardinalby/ts-raii-scope实现