Can I detect async/await available in browser? [duplicate]
Asked Answered
I

2

10

As title, how can I detect async/await es7 support in browser?

Is that possible?

Incise answered 9/9, 2017 at 4:3 Comment(3)
Not exactly detection: kangax.github.io/compat-table/esnextBunker
Also: caniuse.com/#search=awaitBunker
async/await is ES2017.Aqua
A
14

As any other syntactic feature, it should be evaluated in order to be detected. Since eval can be restricted, this may be impossible when CSP is enabled:

let isAsync = true;

try {
  eval('async () => {}');
} catch (e) {
  if (e instanceof SyntaxError)
    isAsync = false;
  else
    throw e; // throws CSP error
}

If there's a chance that target browsers don't support a feature, the code should be transpiled.

The alternative that allows to avoid CSP restrictions on eval is to use external script to detect syntactic features, as described here.

Aqua answered 9/9, 2017 at 4:18 Comment(5)
This will also throw this exception if the browser/js-interpreter doesn't support arrow-functions. When a browser supports the async-keyword, it is not guaranteed that it also supports arrow-functions. Even though it may in practice be most-likely the case that if asnyc is supported, arrow functions are supported as well.Feoff
@StefanSteiger No, this part is guaranteed, async/await is ES2017 and arrows are 2015, there were no inconsistencies with their support in engines. The whole script will just fail to execute when running in ES5 environment because of "let"Aqua
Ah yes, and that with let too. Well, not necessarely. IE11 supports generators, which means you can polyfill promises. But then, it doesn't support arrow functions, and you can't polyfill that, because this is an engine-level feature. Then you can use TypeScript to transpile await down to ES5. Then you have working await support in es5, and your check will fail ;) OK, granted this is borderline, and IE is finally history, hopefully, but i'm just saying. However, potentially the same issues exist with old versions of Safari. But you're right, you also need to change let to var for ES5.Feoff
On a sidenote, just because arrows are in ES2015, there is no guarantee that all browsers implemented ES2015 completely. Though again, since arrow functions are so popular, although they are 30% slower, it's unlikely anything modern doesn't implement them. But it is always possible. It is an unnecessary feature after all.Feoff
@StefanSteiger I paid some attention to the arrival of ES2015, iirc this ended up with all evergreen engines implemented main syntax features consistently when no experimental flags are used. Any way, the practical meaning of such snippet is to provide a fallback for older browsers. In this case var can be used instead of let if this should work in any browser and not just reasonably outdated, and eval should contain a feature of the app target ES spec to test (async and ES2017 in this case)Aqua
C
4

Currently there is no perfect solution for that, but it can be done using eval:

let isAsyncSupported;

try {
  isAsyncSupported = eval(`typeof Object.getPrototypeOf(async function() {}).constructor === 'function'`);
} catch (exception) {
  isAsyncSupported = false;
}

For more see:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

Clash answered 9/9, 2017 at 4:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.