Say I have this function (psuedo-code) :
function Foo() {
let varThatRequiresCleanup = //something
if(condition1) {
return Error1;
}
if(condition2) {
return Error2;
}
if(condition3) {
return Error3;
}
//etc.. more ifs and important code.
varThatRequiresCleanup.CleanUp();
return Success;
}
Coming from the C++ & C world I would just implement the cleaning up in the destructor or use a goto
but JavaScript doesn't have either.
How would I go about calling CleanUp()
whenever Foo()
returns?
Is the only method to call CleanUp()
in every if
that I return in?
Say I have this function (psuedo-code) :
function Foo() {
let varThatRequiresCleanup = //something
if(condition1) {
return Error1;
}
if(condition2) {
return Error2;
}
if(condition3) {
return Error3;
}
//etc.. more ifs and important code.
varThatRequiresCleanup.CleanUp();
return Success;
}
Coming from the C++ & C world I would just implement the cleaning up in the destructor or use a goto
but JavaScript doesn't have either.
How would I go about calling CleanUp()
whenever Foo()
returns?
Is the only method to call CleanUp()
in every if
that I return in?
- checkout this answer: stackoverflow./a/42335949/5549391 – agDev Commented Oct 25, 2018 at 19:31
- This depends on what you're trying to achieve. What is this variable and why does it require cleanup? It's in function scope and will be garbage-collected. – Estus Flask Commented Oct 25, 2018 at 19:41
5 Answers
Reset to default 3One alternative could be to use a function for the repeating code :
function Foo() {
let varThatRequiresCleanup = //something
function CleanUpAndReturn(returnValue) {
varThatRequiresCleanup.CleanUp();
return returnValue;
}
if (condition1) { return CleanUpAndReturn(Error1); }
if (condition2) { return CleanUpAndReturn(Error2); }
if (condition3) { return CleanUpAndReturn(Error3); }
//etc.. more ifs and important code.
return CleanUpAndReturn(Success);
}
You can use a try-finally block:
function Foo() {
let varThatRequiresCleanup = //something
try {
if(condition1) {
return Error1;
}
if(condition2) {
return Error2;
}
if(condition3) {
return Error3;
}
//etc.. more ifs and important code.
return Success;
} finally {
varThatRequiresCleanup.CleanUp();
}
}
In javascript, you can define and call functions, in functions (ie in closures).
By this, you could achieve what you need in this way:
function Foo() {
let varThatRequiresCleanup = //something
// Define your "actual" Foo logic in an inner function
// where you can define your flow and return logic as
// needed.
function InnerFoo() {
// You can access variables in the Foo closure, like so
console.log(varThatRequiresCleanup);
if(condition1) {
return Error1;
}
if(condition2) {
return Error2;
}
if(condition3) {
return Error3;
}
//etc.. more ifs and important code.
return Success;
}
// Now call your inner function like so
var result = InnerFoo();
// Now you can cleanup resourced in scope of Foo as
// in this way, because this line will be hit
varThatRequiresCleanup.CleanUp();
// Return the result from InnerFoo()
return result;
}
You can do something called a monkey patch.
Concept taken from here.
function foo(){
if(condition1) {
return Error1;
}
if(condition2) {
return Error2;
}
if(condition3) {
return Error3;
}
}
var tempFoo = foo;
window.foo = function() {
tempFoo();
//do the cleanup here
CleanUp();
}
You could use a proxy to intercept calls to your methods.
It works by returning a new Proxy
to the constructor. We then handle the get
calls, and with that we can first call the method, then run the clean up afterwards. This will allow us to only have to call cleanup once within the proxy, and not within the method itself.
- Create instance which returns a new proxy
- Call one of the methods
- The proxy will intercept and handle the call now
- The proxy will run the function as it would have been
- The proxy will then run the cleanup function
- The proxy will then return the result from step 2
class MyClass {
constructor() {
this.varThatRequiresCleanup = null
// Create a reference to `this` so the function below can use it
let $this = this
// A private function this will clean stuff up
// We can't use `this` in this function because it references window
// We will use our reference `$this` instead
function cleanup() {
$this.varThatRequiresCleanup = null
console.log('cleaned up')
}
// Create a proxy that will handle the method calls
return new Proxy(this, {
get: (target, prop, receiver) => {
// Get the called property
let targetValue = Reflect.get(target, prop, receiver)
// Execute the called property
return (...args) => {
let r = targetValue.apply(this, args)
console.log('before varThatRequiresCleanup:', this.varThatRequiresCleanup)
cleanup()
console.log('after varThatRequiresCleanup:', this.varThatRequiresCleanup)
return r
}
}
})
}
Foo() {
this.varThatRequiresCleanup = 'foo'
return 'foo result'
}
Bar() {
this.varThatRequiresCleanup = 'bar'
return 'bar result'
}
}
let c = new MyClass()
console.log('Foo Return Value:', c.Foo())
console.log('-----------')
console.log('Bar Return Value:', c.Bar())
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744169854a4561482.html
评论列表(0条)