I just read about async functions
and found some similar features for ES2017. It's causing a lot of confusion and I just want to ask:
async function
, AsyncFunction
(used to create an async function), and an async function expression (which I think is just another async function)? Highlights of everyone's quirks and performances would be greatly appreciated!
There are four ways to create functions in Javascript. There are also four ways to create asynchronous functions in Javascript, which are exact mirrors of each other.
To demonstrate how this works, I used a simple
sleep
function, declared globally:Function declaration
This is the simplest way to declare a function. It can be declared once and hoisted to the top of the current function scope.
Function declarations are exactly the same as async function declarations, except that
async
functions always return a Promise and allow you to useawait
.Function expression
Function expressions look very much like function declarations. However, they are not promoted to the top of the function scope. You can redefine them as many times as needed. They can be defined inline. They can be anonymous or named: if they are named, the name refers to a function within that function's scope.
Function expressions are exactly the same as async function expressions, except that
async
functions always return a Promise and allow you to useawait
.Arrow function
Arrow functions are a quick and short way to define a function, introduced in ES2015 (ES6). They are equivalent in most respects to function expressions, except that they are always anonymous, and the value of
this
is always lexically bound, i.e. inherited from the outer scope.Arrow functions are exactly the same as async arrow functions, except that
async
functions always return a Promise and allow you to useawait
. (They are slightly different in the above statements because there are multiple statements inside each async function. This means that these statements need to be contained in a block{}
andreturn
Need to be explicit. This is also true for ordinary arrow functions longer than one statement.)Function constructor
The function constructor allows you to dynamically define functions using strings. Note that they always run in the global scope and have no access to the scope in which they are defined. They are only useful in rare circumstances. Personally I don't think an async function constructor would be useful. The author of ES2017 agrees with me, since
AsyncFunction
is not a global object and must be obtained first usingconst AsyncFunction = Object.getPrototypeOf(async function(){}).constructor
.Functions created using the function constructor are exactly the same as functions created using the anonymous function constructor, except that the
async
function always returns a Promise and allows you to useawait
. (But you already guessed it, right?)