目錄
定義 async 函數
await 關鍵字
了解語句的執行順序
通过 Fetch API 使用 asyncawait
最终想法
首頁 web前端 js教程 探索 JavaScript 中 async 和 wait 的威力

探索 JavaScript 中 async 和 wait 的威力

Aug 31, 2023 pm 03:33 PM

探索 JavaScript 中 async 和 wait 的威力

在我之前的教學中,我們介紹了 JavaScript 中 Promise 的基礎知識。我在文章的最後說,promise 允許我們非同步運行我們的程式碼。

在本教程中,我們將學習 JavaScript 中的 asyncawait 關鍵字,它們使我們能夠有效地使用 Promise 並編寫更簡潔的非同步程式碼。

定義 async 函數

讓我們從非同步函數開始討論。考慮以下問候語函數:

function greet() {
  return "Hello, World!";
}

// Outputs: Hello, World!
console.log(greet());
登入後複製

這只是我們之前見過的常規 JavaScript 函數。它所做的只是傳回一個字串,上面寫著「Hello, World!」不過,我們可以將其變成非同步函數,只需在其前面加上async 即可,如下所示:

async function greet() {
  return "Hello, World!";
}

// Outputs: Promise { <state>: "fulfilled", <value>: "Hello, World!" }
console.log(greet());
登入後複製

這次,函數傳回一個 Promise 對象,其 state 屬性設定為已完成,值設定為 Hello, World! 換句話說,promise 已成功解析。

我們仍然回傳字串「Hello, World!」在函數定義裡面。但是,使用 async 關鍵字意味著傳回值將包裝在已解析的 Promise 物件中。已解決的 Promise 的值將與我們從 async 函數傳回的值相同。

您也可以從 async 函數傳回您自己的承諾,如下所示:

async function greet() {
  return Promise.resolve("Hello, World!");
}

// Outputs: Hello, World!
greet().then((value) => console.log(value));
登入後複製

基本上,async 關鍵字幫助我們定義始終傳回承諾的函數。您可以自己明確地傳回一個 Promise,也可以讓函數將任何不是 Promise 的回傳值包裝到 Promise 中。

await 關鍵字

任何 async 函數都可以包含零個或多個 await 表達式。重要的是要記住 await 關鍵字僅在 async 函數內有效。 await 關鍵字用於等待 Promise 解析或拒絕,然後取得已完成的值。

我們使用 await 關鍵字,語法如下:

await expression
登入後複製

表達式可以是原生的Promise,這種情況下直接使用,原生等待。在這種情況下,不會有對 then() 的隱式呼叫。表達式可以是 thenable 對象,在這種情況下,將透過呼叫 then() 方法建構一個新的 Promise 。此表達式也可以是不可thenable 的值。在這種情況下,將建立一個已經實現的 Promise 供我們使用。

假設一個承諾已經兌現了。 async 函數的執行仍然會暫停,直到下一個tick。記住這一點很重要。

以下是在 async 函數中使用 await 關鍵字的範例:

async function greet() {
  let greeting = await "Hello, World!";
  return greeting;
}

// Outputs: [Function: Promise]
console.log(greet().constructor);

// Outputs: Hello, World!
greet().then((msg) => console.log(msg));
登入後複製

這是在明確使用 Promise 時將 await 關鍵字與 async 函數結合使用的另一個範例:

async function greet() {
  let greeting = new Promise((resolve) => {
    setTimeout(() => {
      resolve("Hello, World!");
    }, 2000);
  });
  
  return greeting;
}

// Outputs: [Function: Promise]
console.log(greet().constructor);

// Outputs: Hello, World!
greet().then((msg) => console.log(msg));
登入後複製

這次,我們明確地使用了一個在 2 秒內解析的 Promise。因此,「Hello, World」問候語將在兩秒後列印。

了解語句的執行順序

我們現在將編寫兩個不同的問候函數並查看它們輸出結果的順序。

function n_greet(person) {
  return `Hello, ${person}!`;
}

async function a_greet(person) {
  let greeting = await `Hello, ${person}!`;
  return greeting;
}
登入後複製

我們的第一個函數 n_greet() 是一個傳回字串作為輸出的普通函數。我們的第二個函數是 async 函數,它在 await 關鍵字之後使用表達式。本例中的回傳值是一個已經履行的承諾。

這是呼叫所有這些函數並記錄輸出的程式碼片段:

a_greet("Andrew").then((msg) => console.log(msg));
console.log(n_greet("Adam"));

/* Output in order:
Hello, Adam!
Hello, Andrew! */
登入後複製

問候 Adam 的 n_greet() 函數呼叫已結束。然而,他在輸出中首先受到歡迎。這是因為函數呼叫直接傳回一個字串。

a_greet() 函數呼叫是在開始時向 Andrew 打招呼的,它導致了一個已經履行的承諾的建構。然而,執行仍然暫停,直到下一個時脈週期。這就是為什麼輸出問候語出現在對 Adam 的問候語之後。

現在,我們將定義一個稍微複雜一點的 async 函數,其中包含多個語句。這些語句之一將具有 await 關鍵字。您將看到,在 async 函數中使用 await 關鍵字會暫停執行 await 語句之後的其他語句。

function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms))    
}

async function aa_greet(person) {
  console.log("Before Await..."); 
  await timeout(2000);
  let greeting = `Hello, ${person}!`;
  console.log("After Await...");
  
  return greeting;
}

登入後複製

我們的 async 函數包含一個明確定義的 Promise,前面有 await 關鍵字。這意味著 await 關鍵字將等待 Promise 被履行,然後傳回已履行的值。該承諾將需要 2 秒才能實現,因此大約 2 秒後我們應該在控制台日誌中看到「After Await...」。

這是程式碼片段,它將記錄我們的 async 函數的一些語句:

console.log("Before Greeting Function...");
aa_greet("Monty").then((msg) => console.log(msg));
console.log("After Greeting Function...");

/* Output in Order
23:42:15.327 Before Greeting Function...
23:42:15.331 Before Await...
23:42:15.331 After Greeting Function...
23:42:17.333 After Await...
23:42:17.333 Hello, Monty! */
登入後複製

首先记录字符串“Before Greeting Function...”,因为这是我们进行的第一次调用。之后,我们调用 aa_greet() 函数。这会导致输出字符串“Before Await...”。然后,浏览器遇到 await 关键字。所以它等待承诺解决。与此同时,aa_greet()函数之外的代码继续执行。这就是为什么我们在下一个日志条目中得到“After Greeting Function...”字符串作为输出。

一旦承诺得到解决,浏览器就会继续执行,我们会得到“After Await...”作为输出。最后,我们解析的问候语作为承诺返回,因为我们使用 async 函数。我们对这个已解决的 Promise 调用 then() 方法并记录“Hello, Monty!”到控制台。

通过 Fetch API 使用 asyncawait

await 关键字的一个常见用例是从远程 API 获取数据。这允许比嵌套回调或承诺链更干净的代码。

async function getData() {
    // use the fetch API to fetch data from an API endpoint
    const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
    
    // check if the response is okay (HTTP status code 200-299)
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    
    // parse the response as JSON
    const data = await response.json();
    
    return data;
}
登入後複製

在此函数中,首先我们等待对 API 查询的初始响应。如果响应正常,我们就会等待 JSON 格式的完整响应数据。我们返回 JSON 数据,但请记住,由于这是一个异步函数,因此我们实际上返回一个最终解析为该数据的 Promise。因此,如果您想访问结果数据,您必须再次使用类似await关键字的东西!

const data = await getData();
登入後複製

最终想法

在上一篇教程中了解了 Promise 对象后,我们在本教程中讨论了 async 函数和 await 关键字。您现在应该能够编写自己的 async 函数,使用 await 关键字来使用更清晰、更易读的代码实现基于 Promise 的行为。

以上是探索 JavaScript 中 async 和 wait 的威力的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何創建和發布自己的JavaScript庫? 如何創建和發布自己的JavaScript庫? Mar 18, 2025 pm 03:12 PM

文章討論了創建,發布和維護JavaScript庫,專注於計劃,開發,測試,文檔和促銷策略。

如何在瀏覽器中優化JavaScript代碼以進行性能? 如何在瀏覽器中優化JavaScript代碼以進行性能? Mar 18, 2025 pm 03:14 PM

本文討論了在瀏覽器中優化JavaScript性能的策略,重點是減少執行時間並最大程度地減少對頁面負載速度的影響。

前端熱敏紙小票打印遇到亂碼問題怎麼辦? 前端熱敏紙小票打印遇到亂碼問題怎麼辦? Apr 04, 2025 pm 02:42 PM

前端熱敏紙小票打印的常見問題與解決方案在前端開發中,小票打印是一個常見的需求。然而,很多開發者在實...

如何使用瀏覽器開發人員工具有效調試JavaScript代碼? 如何使用瀏覽器開發人員工具有效調試JavaScript代碼? Mar 18, 2025 pm 03:16 PM

本文討論了使用瀏覽器開發人員工具的有效JavaScript調試,專注於設置斷點,使用控制台和分析性能。

如何使用源地圖調試縮小JavaScript代碼? 如何使用源地圖調試縮小JavaScript代碼? Mar 18, 2025 pm 03:17 PM

本文說明瞭如何使用源地圖通過將其映射回原始代碼來調試JAVASCRIPT。它討論了啟用源地圖,設置斷點以及使用Chrome DevTools和WebPack之類的工具。

誰得到更多的Python或JavaScript? 誰得到更多的Python或JavaScript? Apr 04, 2025 am 12:09 AM

Python和JavaScript開發者的薪資沒有絕對的高低,具體取決於技能和行業需求。 1.Python在數據科學和機器學習領域可能薪資更高。 2.JavaScript在前端和全棧開發中需求大,薪資也可觀。 3.影響因素包括經驗、地理位置、公司規模和特定技能。

開始使用Chart.js:PIE,DONUT和BUBBLE圖表 開始使用Chart.js:PIE,DONUT和BUBBLE圖表 Mar 15, 2025 am 09:19 AM

本教程將介紹如何使用 Chart.js 創建餅圖、環形圖和氣泡圖。此前,我們已學習了 Chart.js 的四種圖表類型:折線圖和條形圖(教程二),以及雷達圖和極地區域圖(教程三)。 創建餅圖和環形圖 餅圖和環形圖非常適合展示某個整體被劃分為不同部分的比例。例如,可以使用餅圖展示野生動物園中雄獅、雌獅和幼獅的百分比,或不同候選人在選舉中獲得的投票百分比。 餅圖僅適用於比較單個參數或數據集。需要注意的是,餅圖無法繪製值為零的實體,因為餅圖中扇形的角度取決於數據點的數值大小。這意味著任何占比為零的實體

初學者的打字稿,第2部分:基本數據類型 初學者的打字稿,第2部分:基本數據類型 Mar 19, 2025 am 09:10 AM

掌握了入門級TypeScript教程後,您應該能夠在支持TypeScript的IDE中編寫自己的代碼,並將其編譯成JavaScript。本教程將深入探討TypeScript中各種數據類型。 JavaScript擁有七種數據類型:Null、Undefined、Boolean、Number、String、Symbol(ES6引入)和Object。 TypeScript在此基礎上定義了更多類型,本教程將詳細介紹所有這些類型。 Null數據類型 與JavaScript一樣,TypeScript中的null

See all articles