0

Is there some way to distinguish a request for the then function (or its call) from await?

I would like to do something like this:

var myProxy = new Proxy(myPromise, {
    get: (t, k) => {
        if (k == 'then') {
            if (/* from await? */) console.log('from await')
            else console.log('without await')
        }
    }
});

Essentially, I need to distinguish between the following two options for calling then:

var a = await myProxy;

var b = myProxy.then(res => /* something */);
Alex
  • 1,457
  • 1
  • 13
  • 26
  • 2
    "*I need to distinguish*" why? Seems like [an XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – VLAZ Jan 22 '21 at 19:23
  • additionally, `.then()` in both instances are identical. They are methods of the Promise object with nothing that uniquely identifies them. – Randy Casburn Jan 22 '21 at 19:27
  • @VLAZ To better understand how it works. – Alex Jan 22 '21 at 19:31
  • 2
    `await` shouldn't be uniquely identifiable. Not unless you try to examine the call chain, then reverse-parse the source code and try to do analysis on the call site. That's not something any sane application should ever use, though, so there is no real **need** for this functionality. – VLAZ Jan 22 '21 at 19:36

1 Answers1

1

No, you cannot, and you also should not.

You can distinguish a direct then call where the caller passes only a single argument (await always passes both), and you could possibly distinguish that a user-defined function is passed not some native resolver functions. However, you can never distinguish await value from Promise.resolve(value).then(…).

(async () => {
   const thenable = {then: console.log};
   
   thenable.then();
   thenable.then(() => {});
   thenable.then(res => {}, err => {});
   Promise.resolve(thenable);
   await thenable;
 })();

(Btw, no reason to use a Proxy if all you want is to intercept a single method.)

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • In principle, this partially solves my task. Thus, we can assert that if at least one of the `then` arguments after `toString()` does not return `function () {[native code]}` the call to `then` originated from the user. Unfortunately, the opposite is not true as we get the same result if the user calls for example `.then(console.log, console.log)`. To completely close the task by this way, it is enough to get `"[native code]"` in the form of an array of bytes or an encoded string or the like. Is there such a possibility? – Alex Jan 23 '21 at 09:25
  • @Alex Is `fn.toString()` what you are looking for? – Bergi Jan 23 '21 at 13:29