There are four ways to create a function in Javascript. There are also four ways to create an asynchronous function in Javascript, and they are exact mirrors of each other.
To demonstrate how this works, I use the simple sleep function, declared globally:
function sleep(time) { return new Promise(function(resolve, reject) { setTimeout(function() { resolve(); }, time); }); }
Function Declaration
function speak() { return 'Hi'; } async function speak() { await sleep(1000); return 'Hi'; }
This is the easiest way to declare a function. It can be declared once and raised to the top of the current scope.
Function declarations and asynchronous function declarations are exactly the same, except that the async function always returns a promise and allows await to be used.
Function Expressions
let speak = function() { return 'Hi'; } // anonymous function expression let speak = function speakFn() { return 'Hi'; } // named function expression let speak = async function() { await sleep(1000); return 'Hi'; } // anonymous asynchronous function expression let speak = async function speakFn() { await sleep(1000); return 'Hi'; } // named asynchronous function expression
Functional expressions are very similar to function declarations. However, they do not rise to the top of the function area. You can redefine them as many times as you like. They can be defined as embedded. They can be either anonymous or named: if they are named, then the name refers to the function within this function.
Functional expressions and asynchronous function expressions are exactly identical, except that the async function always returns a promise and allows await to be used.
Arrow functions
let speak = word => 'Hi ' + word; // one parameter let speak = (word1, word2) => 'Hi ' + word1 + word2; // multiple parameters let speak = async word => { await sleep(1000); return 'Hi ' + word; } // one parameter let speak = async (word1, word2) => { await sleep(1000); return 'Hi ' + word1 + word2; } // multiple parameters
Arrow Functions is a quick and short way to determine the function introduced in ES2015 (ES6). In most cases, they are equivalent to function expressions, except that they are always anonymous, and the value of this always lexically related, that is, inherited from the external area.
The arrow functions and the asynchronous arrow functions are exactly identical, except that the async function always returns a promise and allows await to be used. (They are slightly different in the above statements, because in asynchronous functions each of them has more than one statement. This means that the statements must be enclosed in the {} block, and return must be explicit. True for ordinary arrow functions that contain more one operator.)
Function constructors
let speak = new Function('word', 'return "Hi " + word;'); let speak = new AsyncFunction('word', 'await sleep(1000); return "Hi " + word;')
Function constructors allow you to dynamically define a function using strings. Note that they always run in the global area and do not have access to the area in which they were defined. They are only useful in a very small set of circumstances . I personally don't see how an asynchronous function constructor will ever be useful. ES2017 authors agree with me because AsyncFunction not a global object and must first be obtained using const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor .
Functions created using the constructor of functions and functions created using the anonymous constructor of functions are exactly identical, except that the async function always returns a promise and allows await to be used. (But you guessed it, right?)