How to detect async function support without eval?

Suggested eval way will give false negatives for CSP errors because they are not handled. If this is a problem, CSP errors can be handled as shown in this answer.

It is possible to do that, but the solution is not pretty at all and involves external script. The script can set a flag, or global error handler can be set up to watch for syntax errors when the script is loaded.

If the script results in syntax error, it is still considered loaded, so network problems cannot cause false positives:

async-detection.js

window.isAsyncAvailable = true;
async () => {};

main.js

new Promise(function (resolve, reject) {
  var script = document.createElement('script');
  document.body.appendChild(script);
  script.onload = resolve.bind(null, true);
  script.onerror = reject;
  script.async = true;
  script.src = 'async-detection.js';
})
.then(function () {
  console.log(window.isAsyncAvailable);
})
.catch(/* generic script loading error */);

This method can be used to detect syntactic features used on the website that cannot be polyfilled or normally caught with try..catch. It is particularly useful to reliably trigger Your browser is outdated nag screen.


Extending upon the brilliant ideas in @Estus Flask's answer...

var div = document.createElement("div");
div.innerHTML = '<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==" onload="async () => {}; window.isAsyncAvailable = true;">'

This creates a DIV in memory, then appends an IMG within it that uses a Base64 Encoded Pixel while also leveraging this trick to run the eval so that you don't need to define the external script nor have an external image to load. This can also be simplified into a one-liner:

document.createElement("div").innerHTML = '<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==" onload="async () => {}; window.isAsyncAvailable = true;">';

However, this runs afoul of some CSP configurations. If this pertains to you, then @Estus Flask's external script is your go-to.