Reputation: 543
I have some objects that I am fetching from a web server. Some of the attributes of the objects require additional async parsing, but I want to do that lazily for performance reasons. I am trying to use a proxy to intercept the access and then parse the attribute if accessed. My handler would look something like this
class MyClass {
type() {
return "my new class";
}
}
let myObject = new MyClass();
let proxy = new Proxy(myObject, {
get: async(target, prop, receiver) => {
if (prop === "attribute") {
let newProp = prop + "_parsed";
if (!(newProp in target)) {
return await (new Promise((resolve, reject) => { resolve("parsed value") }));
}
else {
return target[newProp];
}
}
else {
return Reflect.get(target, prop, receiver);
}
},
});
console.log(proxy.attribute); // "parsed value"
console.log(proxy.type()); // "my new class"
If this worked, I would expect to see
parsed value
my new class
but I am getting the following:
{}
{
"message": "Uncaught TypeError: proxy.type is not a function",
"filename": "https://stacksnippets.net/js",
"lineno": 41,
"colno": 19
}
Is there any way I can return an asynchronous value through a proxy but have the calling code think it is just accessing an attribute? I am even open to forcing the "parse" logic (represented by the promise) to be synchronous, however that has portions that are async so I am not sure how to do that.
Upvotes: 5
Views: 5011
Reputation: 665276
You cannot (should not) use an async
method for the get
trap. These always return promises, and you want .type
to return a function. You'd want to use
async function parseValue() {
await new Promise(resolve => setImmediate(resolve));
return "parsed value";
}
let proxy = new Proxy(myObject, {
get(target, prop, receiver) {
if (prop === "attribute") {
let newProp = prop + "_parsed";
if (!(newProp in target)) {
target[newProp] = parseValue();
}
return target[newProp];
} else {
return Reflect.get(target, prop, receiver);
}
},
});
…
console.log(await proxy.attribute);
console.log(proxy.type());
Upvotes: 5