首頁  >  問答  >  主體

ES 2017: async函數 vs AsyncFunction物件 vs async函數表達式

我剛剛閱讀了有關 async 函數 的內容,並發現了 ES2017 的一些類似功能。它造成了很多混亂,我只想問:

  1. async functionAsyncFunction(用於建立非同步函數)和非同步函數表達式(我認為這只是另一個非同步函數)之間有什麼區別?
  2. 什麼時候應該使用一種格式而不是另一種格式?

強調每個人的怪癖和表現將不勝感激!

P粉459440991P粉459440991207 天前359

全部回覆(1)我來回復

  • P粉287726308

    P粉2877263082024-03-26 00:44:29

    在 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。 (但你已經猜到了,對吧?)

    回覆
    0
  • 取消回覆