非同步處理

更新 發佈閱讀 7 分鐘

簡要說明 JavaScript 的 Event Loop

JavaScript 是單執行緒 (single-threaded) 語言,這意味著它一次只能執行一件事,因此所有函式都需要排隊等待執行,這被稱為同步 (synchronous)。在同步操作中,若函式過多或過於複雜,會導致程式阻塞 (blocking),網頁卡住。

為了解決阻塞問題,JavaScript 引入了非同步 (asynchronous) 機制,允許程式碼並發 (concurrency) 運作。非同步操作避免了阻塞,使網頁更加順暢。非同步的運作涉及三個主要部分:Call stack、Web API 和 Callback queue。

  • Call stack:追蹤呼叫的函式,處理同步任務。
  • Web API:處理非同步任務(如 setTimeout),並將完成的任務送到 Callback queue。
  • Callback queue:存放已完成的非同步任務,等待重新進入 Call stack。

Event loop 是個守衛,不斷檢查 Call stack 是否為空。如果 Call stack 為空,它會將 Callback queue 中的回調函式 (callback function) 移回 Call stack 中執行。

這樣,JavaScript 能在單執行緒的基礎上處理非同步任務,保持網頁的流暢性。


那我們來看一下例子

console.log(‘hi’);

setTimeout(function cb(){
console.log(‘there’);
}, 5000);

console.log(‘JSConfEU’)

產出結果順序將會是 :

  1. 'hi'
  2. 'JSConfEU'
  3. 'there'


步驟解析

  • 執行 console.log('hi')這是一個同步操作,直接在主線程上執行,並立即輸出 "hi"
  • 執行 setTimeout(function cb(){console.log('there')},5000):setTimeout 是一個非同步操作。它會安排一個計時器,並將回調函式 cb 註冊到 Web API 中,計時5000毫秒(5秒)。此時,計時器開始倒數計時,並將回調函式 cb 放到 Web API 中,等待計時結束。註冊計時器的操作是同步的,所以立即返回,並繼續執行接下來的程式碼。
raw-image


  • 執行 console.log('JSConfEU')這是一個同步操作,直接在主線程上執行,並立即輸出 "JSConfEU"
raw-image


  • 5秒後,計時器完成,回調函式 cb 被移至 Callback queue 中:Event loop 檢查到 Call stack 為空,將回調函式 cb 移入 Call stack 中執行。執行 console.log('there'),並輸出 "there"
raw-image



Callback Function

Callback 是一種將函式 B 作為參數傳遞給函式 A 的方式,透過函式 A 在適當的時候執行函式 B。這樣做的目的是控制函式執行的順序,通常在需要滿足特定條件後才執行函式 B。

function greet(name, callback) {
console.log("Hello, " + name);
callback();
}

function sayGoodbye() {
console.log("Goodbye!");
}

greet("Alice", sayGoodbye);


  1. greet 函式:接受一個名字和一個回調函式,首先打印 "Hello, [名字]",然後執行回調函式。
  2. sayGoodbye 函式:只打印 "Goodbye!"
  3. 呼叫 greet:傳遞名字 "Alice"和回調函式 sayGoodbye,先打印 "Hello, Alice",接著打印 "Goodbye!"


Promise

如果按照Callback剛剛這樣執行的話,會造成函式層層嵌套,而 Promise 解決了這個問題,使程式更易讀。

Promise 有三種狀態:

  • Pending:進行中
  • Resolve:成功
  • Reject:失敗

Promise 通常使用 .then() 來處理成功,.catch() 來處理失敗。

如果把剛剛callback寫成promise的話,會像這樣:

function greet(name) {
return new Promise((resolve, reject) => {
if (!name) {
reject("錯誤");
} else {
console.log("Hello, " + name);
resolve();
}
});
}

function sayGoodbye() {
console.log("Goodbye!");
}

greet("Alice")
.then(() => {
sayGoodbye();
})
.catch(error => {
console.error("Error:", error);
});

可以更清晰地控制函式的執行順序。


async/await

async/await 是基於 Promise 的語法糖,使非同步程式碼看起來像同步執行。

  1. async:定義一個非同步函式。
  2. await:等待 Promise 完成,就像同步程式碼一樣。

這樣寫法更簡潔,不需要 .then,錯誤處理用 trycatch

function greet(name) {
return new Promise((resolve, reject) => {
if(!name){
reject('錯誤')
} else {
console.log("Hello, " + name);
resolve();
}
});
}


function sayGoodbye() {
console.log("Goodbye!");
}

async function main() {
try {
await greet("Alice");
sayGoodbye();
} catch (error) {
console.error("Error:", error);
}
}

main();

留言
avatar-img
郭欣玫的沙龍
3會員
17內容數
郭欣玫的沙龍的其他內容
2024/07/24
主要來講宣告函式跟箭頭函式 : 宣告函式(Function Declaration) 語法: function functionName(parameters) { return result; } 特點: 使用 function 關鍵字 函式名稱是必需的 存在函式
2024/07/24
主要來講宣告函式跟箭頭函式 : 宣告函式(Function Declaration) 語法: function functionName(parameters) { return result; } 特點: 使用 function 關鍵字 函式名稱是必需的 存在函式
2024/07/14
就是指變數可以被訪問和使用的範圍,來說一下var、let和const的作用域差異。 var :function example() { console.log(x); // 輸出: undefined 因為變量提升造成的 var x = 5; } 函數作用域或全域作用域 可以重複宣告
2024/07/14
就是指變數可以被訪問和使用的範圍,來說一下var、let和const的作用域差異。 var :function example() { console.log(x); // 輸出: undefined 因為變量提升造成的 var x = 5; } 函數作用域或全域作用域 可以重複宣告
2024/07/04
一開始你先把你的專案push上去後,修改vite.config.ts ,要在裡面新增  base: "/Cart/" (/放自己的專案名稱/) build: {outDir: "docs"}, 接下來你要去你的github setting 裡面 -> Page ->選Deploy fro
Thumbnail
2024/07/04
一開始你先把你的專案push上去後,修改vite.config.ts ,要在裡面新增  base: "/Cart/" (/放自己的專案名稱/) build: {outDir: "docs"}, 接下來你要去你的github setting 裡面 -> Page ->選Deploy fro
Thumbnail
看更多
你可能也想看
Thumbnail
債券投資,不只是高資產族群的遊戲 在傳統的投資觀念中,海外債券(Overseas Bonds)常被貼上「高資產族群專屬」的標籤。過去動輒 1 萬甚至 10 萬美元的最低申購門檻,讓許多想尋求穩定配息的小資族望而卻步。 然而,在股市波動劇烈的環境下,尋求穩定的美元現金流與被動收入成為許多投資人
Thumbnail
債券投資,不只是高資產族群的遊戲 在傳統的投資觀念中,海外債券(Overseas Bonds)常被貼上「高資產族群專屬」的標籤。過去動輒 1 萬甚至 10 萬美元的最低申購門檻,讓許多想尋求穩定配息的小資族望而卻步。 然而,在股市波動劇烈的環境下,尋求穩定的美元現金流與被動收入成為許多投資人
Thumbnail
透過川普的近期債券交易揭露,探討債券作為資產配置中「穩定磐石」的重要性。文章分析降息對債券的潛在影響,以及股神巴菲特的操作策略。並介紹玉山證券「小額債」平臺,如何讓小資族也能低門檻參與海外債券市場,實現「低門檻、低波動、固定收益」的務實投資方式。
Thumbnail
透過川普的近期債券交易揭露,探討債券作為資產配置中「穩定磐石」的重要性。文章分析降息對債券的潛在影響,以及股神巴菲特的操作策略。並介紹玉山證券「小額債」平臺,如何讓小資族也能低門檻參與海外債券市場,實現「低門檻、低波動、固定收益」的務實投資方式。
Thumbnail
解析「債券」如何成為資產配置中的穩定錨,提供低風險高回報的投資選項。 藉由玉山證券的低門檻債券服務,投資者可輕鬆入手,平衡風險並穩定財務。
Thumbnail
解析「債券」如何成為資產配置中的穩定錨,提供低風險高回報的投資選項。 藉由玉山證券的低門檻債券服務,投資者可輕鬆入手,平衡風險並穩定財務。
Thumbnail
相較於波動較大的股票,債券能提供固定現金流,而玉山證券推出的小額債,更以1000 美元的低門檻,讓學生與新手也能參與全球優質企業債投資。玉山E-Trader平台即時報價、條件式篩選與清楚的交易流程等特色,大幅降低投資難度,對於希望分散風險、建立穩定現金流的人來說,玉山小額債是一個值得嘗試的理財起點。
Thumbnail
相較於波動較大的股票,債券能提供固定現金流,而玉山證券推出的小額債,更以1000 美元的低門檻,讓學生與新手也能參與全球優質企業債投資。玉山E-Trader平台即時報價、條件式篩選與清楚的交易流程等特色,大幅降低投資難度,對於希望分散風險、建立穩定現金流的人來說,玉山小額債是一個值得嘗試的理財起點。
Thumbnail
避免 thread 競速(Race Condition)是多執行緒編程中常見的挑戰之一。 Race Condition 發生在多個執行緒同時訪問和修改共享資源時,因為執行緒之間的執行順序無法預測,可能會導致數據的不一致性或意外行為。 本文主要介紹如何使用Lock來避免此狀況出現。 首先先看沒
Thumbnail
避免 thread 競速(Race Condition)是多執行緒編程中常見的挑戰之一。 Race Condition 發生在多個執行緒同時訪問和修改共享資源時,因為執行緒之間的執行順序無法預測,可能會導致數據的不一致性或意外行為。 本文主要介紹如何使用Lock來避免此狀況出現。 首先先看沒
Thumbnail
在網路速度有限的情況下,依序記錄不斷產生的資訊,能統計使用者在頁面上操作了哪些功能。
Thumbnail
在網路速度有限的情況下,依序記錄不斷產生的資訊,能統計使用者在頁面上操作了哪些功能。
Thumbnail
JavaScript (簡稱 JS) 是具有一級函數的輕量級、直譯式或即時編譯的程式語言。它因為用作網頁的腳本語言而大為知名,但也用於許多非瀏覽器的環境,像是 Node.js 等。由於 JavaScript 語法上的一些缺點,軟體工程師們又設計出了 CoffeeScript、TypeScript 和
Thumbnail
JavaScript (簡稱 JS) 是具有一級函數的輕量級、直譯式或即時編譯的程式語言。它因為用作網頁的腳本語言而大為知名,但也用於許多非瀏覽器的環境,像是 Node.js 等。由於 JavaScript 語法上的一些缺點,軟體工程師們又設計出了 CoffeeScript、TypeScript 和
Thumbnail
本章節主要介紹了JavaScript中的流程控制,包括條件語句(如if、else if、else和三元運算子)和循環結構(如for迴圈、while迴圈等)。同時,也提供了如何使用break、continue和label來控制迴圈的執行。
Thumbnail
本章節主要介紹了JavaScript中的流程控制,包括條件語句(如if、else if、else和三元運算子)和循環結構(如for迴圈、while迴圈等)。同時,也提供了如何使用break、continue和label來控制迴圈的執行。
Thumbnail
簡要說明 JavaScript 的 Event Loop JavaScript 是單執行緒 (single-threaded) 語言,這意味著它一次只能執行一件事,因此所有函式都需要排隊等待執行,這被稱為同步 (synchronous)。在同步操作中,若函式過多或過於複雜,會導致程式阻塞 (blo
Thumbnail
簡要說明 JavaScript 的 Event Loop JavaScript 是單執行緒 (single-threaded) 語言,這意味著它一次只能執行一件事,因此所有函式都需要排隊等待執行,這被稱為同步 (synchronous)。在同步操作中,若函式過多或過於複雜,會導致程式阻塞 (blo
Thumbnail
當你需要在 Python 中執行多個任務,但又不希望它們相互阻塞時,可以使用 threading 模組。 threading 模組允許你在單個程序中創建多個執行緒,這些執行緒可以同時運行,從而實現並行執行多個任務的效果。
Thumbnail
當你需要在 Python 中執行多個任務,但又不希望它們相互阻塞時,可以使用 threading 模組。 threading 模組允許你在單個程序中創建多個執行緒,這些執行緒可以同時運行,從而實現並行執行多個任務的效果。
Thumbnail
非同步程式設計(Asynchronous programming) 或是簡單的稱之為 async,它是一種並發程式模型(concurrent programming model),其目的就是讓多個任務能同時在作業系統的執行緒上執行,並透過 async/.await 保留同步。
Thumbnail
非同步程式設計(Asynchronous programming) 或是簡單的稱之為 async,它是一種並發程式模型(concurrent programming model),其目的就是讓多個任務能同時在作業系統的執行緒上執行,並透過 async/.await 保留同步。
Thumbnail
為什麼需要非同步? 我們在「【Web微知識系列】 Web Workers」有介紹到在瀏覽器可執行腳本Javascript環境底下如何完成非同步的操作, 主要是為了讓任務更有效率的進行, 不會因為一個非常耗時的工作堵塞住整個服務, 導致無法服務他人的窘境。 大家應該經常在餐廳裡會看到服務員協
Thumbnail
為什麼需要非同步? 我們在「【Web微知識系列】 Web Workers」有介紹到在瀏覽器可執行腳本Javascript環境底下如何完成非同步的操作, 主要是為了讓任務更有效率的進行, 不會因為一個非常耗時的工作堵塞住整個服務, 導致無法服務他人的窘境。 大家應該經常在餐廳裡會看到服務員協
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News