異步并發(fā)概述

2024-02-16 13:43 更新

Promise和async/await提供異步并發(fā)能力,是標準的JS異步語法。異步代碼會被掛起并在之后繼續(xù)執(zhí)行,同一時間只有一段代碼執(zhí)行,適用于單次I/O任務的場景開發(fā),例如一次網絡請求、一次文件讀寫等操作。

異步語法是一種編程語言的特性,允許程序在執(zhí)行某些操作時不必等待其完成,而是可以繼續(xù)執(zhí)行其他操作。

Promise

Promise是一種用于處理異步操作的對象,可以將異步操作轉換為類似于同步操作的風格,以方便代碼編寫和維護。Promise提供了一個狀態(tài)機制來管理異步操作的不同階段,并提供了一些方法來注冊回調函數以處理異步操作的成功或失敗的結果。

Promise有三種狀態(tài):pending(進行中)、fulfilled(已完成)和rejected(已拒絕)。Promise對象創(chuàng)建后處于pending狀態(tài),并在異步操作完成后轉換為fulfilled或rejected狀態(tài)。

最基本的用法是通過構造函數實例化一個Promise對象,同時傳入一個帶有兩個參數的函數,通常稱為executor函數。executor函數接收兩個參數:resolve和reject,分別表示異步操作成功和失敗時的回調函數。例如,以下代碼創(chuàng)建了一個Promise對象并模擬了一個異步操作:

  1. const promise = new Promise((resolve, reject) => {
  2. setTimeout(() => {
  3. const randomNumber = Math.random();
  4. if (randomNumber > 0.5) {
  5. resolve(randomNumber);
  6. } else {
  7. reject(new Error('Random number is too small'));
  8. }
  9. }, 1000);
  10. });

上述代碼中,setTimeout函數模擬了一個異步操作,并在1秒鐘后隨機生成一個數字。如果隨機數大于0.5,則執(zhí)行resolve回調函數并將隨機數作為參數傳遞;否則執(zhí)行reject回調函數并傳遞一個錯誤對象作為參數。

Promise對象創(chuàng)建后,可以使用then方法和catch方法指定fulfilled狀態(tài)和rejected狀態(tài)的回調函數。then方法可接受兩個參數,一個處理fulfilled狀態(tài)的函數,另一個處理rejected狀態(tài)的函數。只傳一個參數則表示狀態(tài)改變就執(zhí)行,不區(qū)分狀態(tài)結果。使用catch方法注冊一個回調函數,用于處理“失敗”的結果,即捕獲Promise的狀態(tài)改變?yōu)閞ejected狀態(tài)或操作失敗拋出的異常。例如:

  1. promise.then(result => {
  2. console.info(`Random number is ${result}`);
  3. }).catch(error => {
  4. console.error(error.message);
  5. });

上述代碼中,then方法的回調函數接收Promise對象的成功結果作為參數,并將其輸出到控制臺上。如果Promise對象進入rejected狀態(tài),則catch方法的回調函數接收錯誤對象作為參數,并將其輸出到控制臺上。

async/await

async/await是一種用于處理異步操作的Promise語法糖,使得編寫異步代碼變得更加簡單和易讀。通過使用async關鍵字聲明一個函數為異步函數,并使用await關鍵字等待Promise的解析(完成或拒絕),以同步的方式編寫異步操作的代碼。

async函數是一個返回Promise對象的函數,用于表示一個異步操作。在async函數內部,可以使用await關鍵字等待一個Promise對象的解析,并返回其解析值。如果一個async函數拋出異常,那么該函數返回的Promise對象將被拒絕,并且異常信息會被傳遞給Promise對象的onRejected()方法。

下面是一個使用async/await的例子,其中模擬了一個異步操作,該操作會在3秒鐘后返回一個字符串。

  1. async function myAsyncFunction() {
  2. const result = await new Promise((resolve) => {
  3. setTimeout(() => {
  4. resolve('Hello, world!');
  5. }, 3000);
  6. });
  7. console.info(String(result)); // 輸出: Hello, world!
  8. }
  9. myAsyncFunction();

在上述示例代碼中,使用了await關鍵字來等待Promise對象的解析,并將其解析值存儲在result變量中。

需要注意的是,由于要等待異步操作完成,因此需要將整個操作包在async函數中。除了在async函數中使用await外,還可以使用try/catch塊來捕獲異步操作中的異常。

  1. async function myAsyncFunction() {
  2. try {
  3. const result = await new Promise((resolve) => {
  4. resolve('Hello, world!');
  5. });
  6. } catch (e) {
  7. console.error(`Get exception: ${e}`);
  8. }
  9. }
  10. myAsyncFunction();
以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號