tigercosmos
tigercosmos

Reputation: 345

How to make JavaScript Proxy's handler methods to be async functions?

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!

Upvotes: 5

Views: 1825

Answers (2)

cscan
cscan

Reputation: 374

Not exactly you want, but you may find this help:

let a = Array.from(Array(1000).keys()).map(n =>
   new Proxy({$n: n}, {
      async get (target, name) {
         if (target.$loading !== 1) {
            console.log(`Proxy: Getting the record ${n} from server`)
            await new Promise(resolve => setTimeout(resolve, 1000))
            target.field1 = 1234
            target.field2 = 'abcd'
            target.field3 = true
            target.$loading = 1
         }
         return target[name]
      },
      async set (target, name, value) {
         target[name] = value
         console.log(`Proxy: Setting the record ${n} in server`)
         await new Promise(resolve => setTimeout(resolve, 1000))
         return true
      }
   })
)

console.log(await a[17].field1) // 1234
console.log(await a[17].field2) // abcd
console.log(await a[17].field3) // true
a[17].field3 = false
console.log(await a[17].field3) // false

Upvotes: 0

Bergi
Bergi

Reputation: 665276

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.

Upvotes: 2

Related Questions