-1

I made a module whose task is to proxy the methods of a class and execute functions before or after a method. But the problem we have is that when proxied methods in a class want to call each other, the proxy promise returns in the second layer. Or to put it more simply, functions that are proxied become promises if they are used inside

Code example

class Bar {
    classAlias  = false;
  
    proxyHandle = {
      // little hack where we save refrenece to our class inside the object
      main : this,
      /**
       * The apply will be fired each time the function is called
       * @param  target Called function
       * @param  scope  Scope from where function was called
       * @param  args   Arguments passed to function
       * @return        Results of the function
       */
      apply : async function (target, scope, args) {
        const func_name = target.name;
  
        // console.log('before', func_name);
  
        // let's call some method of this class to actually check if this is the right instance
        // also remember that you have to exclude methods which you are gonna use
        // inside here to avoid “too much recursion” error
        this.main._free.instanceCheck();
  
  
        // here we bind method with our class by accessing reference to instance
        const results = target.bind(this.main)(...args);
  
        // console.log('after', func_name, results);
        return results;
      }
    }
  
    constructor(classAlias) {
      // Get all methods of choosen class
      let methods = Object.getOwnPropertyNames( Bar.prototype );
  
      // Find and remove constructor as we don't need Proxy on it
      let consIndex = methods.indexOf('constructor');
      if ( consIndex > -1 ) methods.splice(consIndex, 1);
  
      // Replace all methods with Proxy methods
      methods.forEach( methodName => {
        this[methodName] = new Proxy( this[methodName], this.proxyHandle );
      });
      this.classAlias = classAlias;
    }
  
    // easies trick to do to avoid infinite loop inside apply is to set your functions
    // inside object, as getOwnPropertyNames from prototype will only get methods
    _free = {
      instanceCheck : () => {
        // this will check if this is our Foo class
        // console.log(this.classAlias);
      }
    }
  
    func1() {
     let test = this.func2()
     console.log(test);
    }

    func2(){
      return 'func2'  
    }
  }


class Foo {
    classAlias = false;
  
    proxyHandle = {
      // little hack where we save refrenece to our class inside the object
      main : this,
      /**
       * The apply will be fired each time the function is called
       * @param  target Called function
       * @param  scope  Scope from where function was called
       * @param  args   Arguments passed to function
       * @return        Results of the function
       */
      apply : function (target, scope, args) {
        const func_name = target.name;
  
        console.log('before', func_name);
  
        // let's call some method of this class to actually check if this is the right instance
        // also remember that you have to exclude methods which you are gonna use
        // inside here to avoid “too much recursion” error
        this.main._free.instanceCheck();
  
  
        // here we bind method with our class by accessing reference to instance
        const results = target.bind(this.main)(...args);
  
        console.log('after', func_name, results);
        return results;
      }
    }
  
    constructor(classAlias) {
      // Get all methods of choosen class
      let methods = Object.getOwnPropertyNames( Foo.prototype );
  
      // Find and remove constructor as we don't need Proxy on it
      let consIndex = methods.indexOf('constructor');
      if ( consIndex > -1 ) methods.splice(consIndex, 1);
  
      // Replace all methods with Proxy methods
      methods.forEach( methodName => {
        this[methodName] = new Proxy( this[methodName], this.proxyHandle );
      });
      this.classAlias = classAlias;
    }
  
    // easies trick to do to avoid infinite loop inside apply is to set your functions
    // inside object, as getOwnPropertyNames from prototype will only get methods
    _free = {
      instanceCheck : () => {
        // this will check if this is our Foo class
        // console.log(this.classAlias);
      }
    }
  
    log() {
        (new Bar('Proxy Class B')).func1();
    }
  }

  /////////////////


  
  (new Foo('Proxy Class A')).log();


  
output :
before log
Promise { 'func2' }
after log undefined

The reason for leaving async

in the apply function

This is because when I want to execute functions before executing the main method, they may be syncronized or synchronous, that's why

But putting async causes another problem that I mentioned

And that is nothing but the non-implementation of nested proxy functions

  • 1
    Calling an `async` function gives you a Promise. That's how they work. – Pointy Aug 22 '23 at 14:10
  • Since you don't use `await` inside the function, the only effect `async` is having is making it return a promise. – Quentin Aug 22 '23 at 14:11
  • Are you wanting to run something `async` before you execute your proxied methods. If so you can't do that with `apply` because it's not designed that way, it's a `sync` method that can be run before, not `async`. If so, somebody asked a similar question yesterday, and a trick you could do monkey patch the methods via `get` instead. https://stackoverflow.com/questions/76944324/how-to-always-apply-a-method-before-executing-another-method-via-a-proxy/76945219#76945219 – Keith Aug 22 '23 at 14:29
  • yes - exactly i want a run some async methods before exectue proxy method . so i should use get instead of apply ? just this? @Keith – reza salari Aug 22 '23 at 18:53
  • can you more explain how i can run some method async before execute proxied method _ @Keith – reza salari Aug 23 '23 at 08:21
  • Hi @rezasalari, if you click on the link I gave, there is an example and explanation there on how to do it. The example shows how to say do an `async connect`, before an `async sendMessage`. I works by intercepting the get, and wrapping into an an async function. – Keith Aug 23 '23 at 09:32
  • @Keith Thank you, I saw your answer but what is the problem, when a proxied method wants to be used in another proxied method, the promise is returned - – reza salari Aug 26 '23 at 06:46
  • And my question is still that if we want to execute a chain of synchronous and asynchronous functions before executing a method, how is it possible? @Keith – reza salari Aug 26 '23 at 06:47

0 Answers0