探索 JavaScript 中 async 和 wait 的威力
在我之前的教學中,我們介紹了 JavaScript 中 Promise 的基礎知識。我在文章的最後說,promise 允許我們非同步運行我們的程式碼。
在本教程中,我們將學習 JavaScript 中的 async
和 await
關鍵字,它們使我們能夠有效地使用 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 使用 async
和 await
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中文網其他相關文章!

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

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

熱門話題

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

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

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

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

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

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