7

我刚刚阅读async functions并遇到了 ES2017 的一些类似功能。它造成了很多混乱,我只想问:

  1. async function, AsyncFunction(用于创建异步函数)和异步函数表达式(我认为这只是另一个异步函数)之间有什么区别?
  2. 我什么时候应该使用一种格式而不是另一种格式?

将不胜感激每个人的怪癖和表现的亮点!

4

1 回答 1

11

有四种方法可以在 Javascript 中创建函数。在 Javascript 中创建异步函数也有四种方法,它们是彼此的精确镜像。

为了演示它是如何工作的,我使用了一个简单的sleep函数,全局声明:

function sleep(time) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve();
        }, time);
    });
}

函数声明

function speak() { return 'Hi'; }
async function speak() { await sleep(1000); return 'Hi'; }

这是声明函数的最简单方法。它可以声明一次并提升到当前函数范围的顶部。

函数声明和异步函数声明完全相同,只是async函数总是返回一个 promise 并允许您使用await.

函数表达式

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

函数表达式看起来很像函数声明。但是,它们并没有提升到函数范围的顶部。您可以根据需要多次重新定义它们。它们可以内联定义。它们可以是匿名的,也可以是命名的:如果它们被命名,则名称指的是该函数范围内的函数。

函数表达式和异步函数表达式完全相同,只是async函数总是返回一个 promise 并允许您使用await.

箭头函数

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

箭头函数是在 ES2015 (ES6) 中引入的一种快速而简短的定义函数的方法。它们在大多数方面等同于函数表达式,除了它们始终是匿名的并且值this始终是词法绑定的,即从外部范围继承。

箭头函数和异步箭头函数完全相同,只是async函数总是返回一个 promise 并允许您使用await. (它们在上面的语句中略有不同,因为每个异步函数中都有多个语句。这意味着语句需要包含在一个块中{}并且return需要显式。对于普通的箭头函数也是如此不止一个语句长。)

函数构造函数

let speak = new Function('word', 'return "Hi " + word;');
let speak = new AsyncFunction('word', 'await sleep(1000); return "Hi " + word;')

函数构造函数允许您使用字符串动态定义函数。请注意,它们始终在全局范围内运行,并且无法访问定义它们的范围。它们仅在极少数情况下有用。我个人看不出异步函数构造函数如何成为有用的东西。ES2017 的作者同意我的观点,因为AsyncFunction它不是一个全局对象,必须先用const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor.

使用函数构造函数创建的函数和使用匿名函数构造函数创建的函数完全相同,只是async函数总是返回一个 Promise 并允许您使用await. (但你已经猜到了,对吧?)

于 2017-02-16T11:11:18.557 回答