我剛剛閱讀了有關(guān) async 函數(shù)
的內(nèi)容,並發(fā)現(xiàn)了 ES2017 的一些類似功能。它造成了很多混亂,我只想問(wèn):
async function
、AsyncFunction
(用於建立非同步函數(shù))和非同步函數(shù)表達(dá)式(我認(rèn)為這只是另一個(gè)非同步函數(shù))之間有什麼區(qū)別? 強(qiáng)調(diào)每個(gè)人的怪癖和表現(xiàn)將不勝感激!
在 Javascript 中建立函數(shù)有四種方法。在 Javascript 中還有四種建立非同步函數(shù)的方法,它們是彼此精確的鏡像。
為了示範(fàn)這是如何運(yùn)作的,我使用了一個(gè)簡(jiǎn)單的 sleep
函數(shù),在全域宣告:
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'; }
這是宣告函數(shù)最簡(jiǎn)單的方法。它可以聲明一次並提升到目前函數(shù)作用域的頂部。
函數(shù)宣告和非同步函數(shù)宣告完全相同,只是 async
函數(shù)總是傳回一個(gè) 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
函數(shù)表達(dá)式看起來(lái)非常像函數(shù)宣告。然而,它們並沒(méi)有被提升到函數(shù)作用域的頂端。您可以根據(jù)需要多次重新定義它們。它們可以內(nèi)聯(lián)定義。它們可以是匿名的,也可以是命名的:如果它們被命名,那麼名稱引用該函數(shù)範(fàn)圍內(nèi)的函數(shù)。
函數(shù)表達(dá)式和非同步函數(shù)表達(dá)式完全相同,只是 async
函數(shù)總是傳回一個(gè) 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
箭頭函數(shù)是一種快速且簡(jiǎn)短的方法定義一個(gè)函數(shù),在 ES2015 (ES6) 中引入。它們?cè)诖蠖鄶?shù)方面與函數(shù)表達(dá)式等效,只是它們始終是匿名的,並且 this
的值始終是詞法綁定的,即從外部作用域繼承。
箭頭函數(shù)和非同步箭頭函數(shù)完全相同,只是 async
函數(shù)總是傳回一個(gè) Promise 並允許您使用 await
。 (它們?cè)谏厦娴恼Z(yǔ)句中略有不同,因?yàn)槊總€(gè)非同步函數(shù)內(nèi)部都有多個(gè)語(yǔ)句。這表示這些語(yǔ)句需要包含在一個(gè)區(qū)塊{}
中,並且return
需要是明確的。這也是正確的超過(guò)一條語(yǔ)句長(zhǎng)度的普通箭頭函數(shù)。)
let speak = new Function('word', 'return "Hi " + word;'); let speak = new AsyncFunction('word', 'await sleep(1000); return "Hi " + word;')
函數(shù)建構(gòu)函數(shù)可讓您使用字串動(dòng)態(tài)定義函數(shù)。請(qǐng)注意,它們始終在全域範(fàn)圍內(nèi)運(yùn)行,並且無(wú)法存取定義它們的範(fàn)圍。它們僅在極少數(shù)情況下有用。我個(gè)人不認(rèn)為非同步函數(shù)構(gòu)造函數(shù)會(huì)有什麼用處。 ES2017的作者同意我的觀點(diǎn),因?yàn)?AsyncFunction
不是全域?qū)ο?,必須先使?const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor
取得。
使用函數(shù)建構(gòu)函式建立的函式和使用匿名函式建構(gòu)函式建立的函式完全相同,只是 async
函式總是傳回一個(gè) Promise 並允許你使用 await
。 (但你已經(jīng)猜到了,對(duì)吧?)