0

I am working on a library and I have this code. I have the following pattern. Let's say there's a function executeWithinScope:

// example 1
function executeWithinScope(callback) {
  // Globally defined variable
  Tracker.currentScope = new Scope(); // {}
  callback();
  Tracker.currentScope = null;
}

Note, that Scope functionality does not matter it might also be an empty object for this example.

Then, I have a function modifyScope that is intended to be used from inside the callback and it modifies the Tracker.currentScope.

// example 2
function modifyScope() {
  Tracker.currentScope.beModified(); // or do something else to the current scope
}

The global variable approach works nicely when callback is not async, but

// example 3
executeWithinScope(async () => {
  modifyScope(); // scope will remain when modifyScope is called
  modifyScope(await somethingAsync()); // scope will be null modifyScope is called
});

I tried experimenting with eval api, but JS functions are lexically scoped, so I could not inject something inside the callback function.

So my question is: is there a way to do a scope injection or a different approach, so that all modifyScope functions that are called within callback are called with the same variable in its context preserving current syntax?

IDEALLY, the code in the example 3 must not be changed at all, only in the executeWithinScope and modifyScope functions.

Also, I could pass scope into the callback and pass it to modifyScope every time I call it, but it makes it annoying to do every time and makes seem redundant.

// example 4
executeWithinScope(async (scope) => {
  modifyScope(scope); // scope will remain when modifyScope is called
  modifyScope(scope, await somethingAsync()); // scope will be null modifyScope is called
});

or even

// example 5
executeWithinScope(async (scope) => {
  modifyScope.call(scope); // scope will remain when modifyScope is called
  modifyScope.call(scope, await somethingAsync()); // scope will be null modifyScope is called
});

Please, let me know of any other strategy. The code really should stay as it is in the example 3

Tim Nimets
  • 348
  • 2
  • 9
  • `executeWithinScope()` doesn't `await` the callback, so it won't wait for the asynchronous operation to finish. – Barmar Mar 21 '23 at 16:12
  • @Barmar that's correct. `executeWithinScope` might be called along side to each other and not be awaited. If we await for the callback, the second `executeWithinScope` would still overwrite the original `currentScope`. And I really want those functions be "concurent" to each other even if they have async callbacks – Tim Nimets Mar 21 '23 at 16:32
  • You can't do that. If you don't `await` the callback, you set `Tracker.currentScope = null;` before the asynchronous code runs. – Barmar Mar 21 '23 at 16:36
  • @Barmar Yes, I understand it. My question is how to inject that `Tracker.currentScope` into all `modifyScope` from inside the callback, but not others. `executeWithinScope` is not function that is called once, there are many of them and so the approach to keep the scope in a global variable does not work. So, I would like to see if there could be other approaches to this – Tim Nimets Mar 21 '23 at 16:40
  • I can't think of a way to do it that doesn't involve passing the Scope object to the callback, so you can have multiple of them instead of a single global. – Barmar Mar 21 '23 at 16:41

0 Answers0