4

I've found that I can't call async functions with $.proxy. My case was that I proxied event listeners so that they'd still have the same context, but as soon as I tried proxying to an async function, it just didn't get called - also, no errors were thrown.

Could anyone explain me why this doesn't work?

The simple example below will allow you to reproduce the issue. When the async keyword is there, the function will not be called. When you remove async, it'll start working.

$('div').on('click', $.proxy(example, this));

async function example() {
  console.log('test');
}
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
macbem
  • 1,180
  • 2
  • 9
  • 21
  • 1
    First of all, why do you use `async` for a function referenced in an event handler, or in this case passed to `$.proxy` to set context and a `this` value, it's not something that is asynchronous. Secondly, why did you think it would work, there's no `await` for the `async` call, which isn't really async? One doesn't have to use `await`, but using `async` the `example` method now returns a promise, and neither `$.proxy` nor the event handler is expecting a promise. – adeneo Jul 26 '17 at 22:04
  • @adeneo thanks a lot, now I get it - it's my first time jumping into async/await, I missed this detail. – macbem Jul 26 '17 at 22:18
  • In this case, `async/await` isn't really needed, there's nothing to wait for, even if there are other asynchronous methods inside `example()`. If that's the case, you can use `async` inside the function, but not when passing it to an event handler, even through `$.proxy` – adeneo Jul 26 '17 at 22:19
  • Yup, I know that, but it's just a simplified example - in my case, the event handler is marked as `async`, so that's necessary. – macbem Jul 26 '17 at 22:28
  • An event handler like that in itself can't be async, it's something that happens when someone does something and triggers an event, so there's no need to "mark" an event handler as "async", just write code the way one usually does. – adeneo Jul 26 '17 at 22:32

1 Answers1

7

$.proxy was awesome many years ago. async/await is ES2017, and we already have bind since ES5:

$('div').on('click', example.bind(this));

So we have async arrows:

const example = async () => {
  console.log('test');
}

$.proxy uses custom $.isFunction check instead of plain typeof fn === 'function' check. This results in false negative for native async functions (transpiled async vs native async). This results from the fact that native async functions are instances of AsyncFunction, not Function directly.

This is another reason why jQuery shouldn't always be used just because it can. jQuery helper functions were indispensable when there were no native alternatives or they were flaky - but aren't anymore.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565