ES 2017:async function vs AsyncFunction(object)vs async function expression

时间:2017-02-16 01:26:47

标签: javascript async-await ecmascript-2017

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

  1. async functionAsyncFunction(用于创建异步函数)和异步函数表达式(我认为只是另一个异步函数)有什么区别?
  2. 我应该何时使用一种格式而不是另一种格式?
  3. 对每个人的怪癖和表现的重点将不胜感激!

1 个答案:

答案 0 :(得分:9)

在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

Arrow functions是定义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;')

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

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