Proxy: await trap?

Hello ECMAScript community,

I have been working with JavaScript Proxies and Promises, and I'm looking for a way to detect whether an object is being awaited using the await keyword or accessed with a chaining operator like .. Currently, JavaScript doesn't seem to have a built-in way to distinguish between these two cases. I was wondering if it would be possible to introduce a new "await trap" or "Promise trap" for Proxies in ECMAScript to handle this scenario.

The main idea is to have a trap that would be called when the object is awaited, allowing the Proxy to take different actions based on whether it's being used as a Promise or as a regular object with chaining.

Here is an example of what I'm trying to achieve:

const handler = {
  get(target, prop, receiver) {
    // Handle regular properties and chaining
  },
  await(target) {
    // Handle await keyword and Promise resolution
  },
};

const p = new Proxy(target, handler);

// Using the object as a Promise
await p;

// Using the object with chaining
p.then;

I would appreciate any thoughts or feedback on this idea. Is there a reason this hasn't been implemented yet, or are there any alternative ways to achieve the same goal?

Thank you for your time and consideration.

await is just sugar for a nested Promise .then, and it's not an observable call by design - so no, there's no trap, and it's very intentionally not something you're allowed to interfere with.

Separately, I think it would be a very confusing world if, for a Promise x, await x and return x in an async function and x.then() (modulo someone monkeying with Promise.prototype.then) didn't do the same thing.

Thank you for your response. I understand the design decision behind not having an "await trap" and the importance of consistency in the language.

In my use case, I am trying to build a library that allows asynchronous queries on data structures. The goal is to provide a chained syntax that simplifies the query writing. Using Proxies, I can achieve this as follows:

await root.item('folder').item('subfolder').item('then').value 
// same but using proxies:
await proxify(root).folder.subfolder.then; // "then" is the name of the file

However, due to the behavior of await, the only identifier I cannot use in this context is then.

Introducing a Symbol.then as an additional alternative to .then for thanables would also help.

Maybe I just have to think about it more...

I appreciate your insight and will continue exploring different approaches to address this challenge.

You may be interested in https://github.com/tc39/proposal-eventual-send

1 Like

It sounds like you need Symbol.thenable.

1 Like

Exactly, that would solve my problem.
Proposal-eventual-send would probably solve the problem too, but it's a little harder to understand.
Is that why the proposal was archived?

Just for the record in this thread:
For the same purpose (To not occupy property-names with foreign functionality) I support the idea of a Symbol.toJSON.

The eventual-send proposal is very much not archived. It hasn't see much activity lately, but our production system actually uses a shim for it. It is meant to pair with the wavy-dot proposal to implement promise pipelining (our in our current implementation, a single letter E helper). There are a few posts in this forum discussing solution to this category of problems, some of which where I've posted more details on these 2 proposals.

No, I expressed myself badly, "Symbol.thenable" is archived.
Good to know that a solution is developing for my problem.
Thank you for your work.