5

Refer the Mozilla document about Proxy()

A simple Proxy example:

const handler = {
  get: function(target, prop, receiver) {
    return Reflect.get(target, prop, receiver);
  },
  set: function(target, prop, receiver) {
    return Reflect.set(target, prop, receiver);
  }
};

const proxy = new Proxy(target, handler);

I have some async functions in get and set, so I would like to let get and set to be async functions.

I expect something like:

const handler = {
  get: async function(target, prop, receiver) {
    await foo();
    return Reflect.get(target, prop, receiver);
  },
  set: async function(target, prop, receiver) {
    await bar();
    return Reflect.set(target, prop, receiver);
  }
};

const proxy = new Proxy(target, handler);

await (proxy.prop1 = xxx);
yyy = await proxy.prop2;

How can I achieve my goal? Thanks!

user3840170
  • 26,597
  • 4
  • 30
  • 62
tigercosmos
  • 345
  • 3
  • 17
  • async should be prepended before the method name. – Fritzdultimate Aug 07 '20 at 14:52
  • 1
    you cannot make these async in that way, where `proxy.prop1 = y` returns a promise. – TKoL Aug 07 '20 at 14:53
  • @Fritzdultimate have you attempted to do what you're suggesting? – TKoL Aug 07 '20 at 14:53
  • @TKoL no but I know that's the method to create an async method/function – Fritzdultimate Aug 07 '20 at 14:56
  • 1
    @tigercosmos if you're prepared to do `await proxy.prop1 = 2;`, then you should equally be prepared to do `await proxy.set(prop1, 2);` which you CAN have be properly async – TKoL Aug 07 '20 at 14:56
  • In other words, don't worry about making a proxy object, just have getter and setter functions that don't try to change how the `=` equals sign works, and await those getter and setter functions. – TKoL Aug 07 '20 at 14:59
  • @TKoL I want to override the behavior of the existing code, and that's why I want to modify at the handler's `set`. – tigercosmos Aug 07 '20 at 15:04
  • 1
    If you want to override the existing code without changing the existing code, then the `=` operator won't already have `await` in front of it. You HAVE to change the existing code in order to make it async. – TKoL Aug 07 '20 at 15:06
  • You could feasibly have the `set` function be async without needing to await anything, but you're going to get unexpected results in places most likely – TKoL Aug 07 '20 at 15:06
  • @TKOL I've found the repo: https://github.com/BlackGlory/async-proxy. Seems it is possible, though I don't really understand how it achieves so. – tigercosmos Aug 07 '20 at 15:13
  • I don't think that does what you've described here. – TKoL Aug 07 '20 at 15:19
  • @tigercosmos In all the set functionalities of the async-proxy library the documentation clearly states "*the return value is not reliable, you should check the results by other means to ensure that the operation is successful.*" – Bergi Aug 07 '20 at 16:17
  • I see. Thank all of you :) – tigercosmos Aug 07 '20 at 16:20

1 Answers1

2

This is not possible. An assignment expression proxy.property = value always1 evaluates to value, not some return value of the proxy's set trap. You cannot make it return an awaitable promise.

1: unless the assignment, including the proxy traps, throws an exception of course.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375