最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript中Promise講解和使用方法代碼

 更新時間:2026年01月26日 10:18:34   作者:新節(jié)  
這篇文章主要介紹了JavaScript中Promise講解和使用方法的相關資料,Promise是處理異步操作的優(yōu)秀方案,可以使代碼更加簡潔、易讀、易維護,避免回調(diào)地獄和嵌套過深的問題,需要的朋友可以參考下

PromiseJavaScript 異步編程的核心解決方案,它解決了傳統(tǒng)回調(diào)地獄問題,提供了更優(yōu)雅的異步控制流。

面試官:談談你對 Promise 的理解?

回答:

Promise 用來解決異步回調(diào)問題,由于 js
是單線程的,很多異步操作都是依靠回調(diào)方法實現(xiàn)的,這種做法在邏輯比較復雜的回調(diào)嵌套中會相當復雜;也叫做回調(diào)地獄;

promise 用來將這種繁雜的做法簡化,讓程序更具備可讀性,可維護性;promise
內(nèi)部有三種狀態(tài),pending,fulfilled,rejected;

pending 表示程序正在執(zhí)行但未得到結果,即異步操作沒有執(zhí)行完畢,

fulfilled 表示程序執(zhí)行完畢,且執(zhí)行成功,

rejected 表示執(zhí)行完畢但失?。贿@里的成功和失敗都是邏輯意義上的;并非是要報錯。

其實,promise 和回調(diào)函數(shù)一樣,都是要解決數(shù)據(jù)的傳遞和消息發(fā)送問題,promise 中的 then
一般對應成功后的數(shù)據(jù)處理,catch 一般對應失敗后的數(shù)據(jù)處理。

一、Promise 基礎概念

1.1 什么是 Promise?

Promise 是一個表示異步操作最終完成或失敗的對象,它有三種狀態(tài):

  • pending(進行中)
  • fulfilled(已成功)
  • rejected(已失?。?/li>

1.2 創(chuàng)建 Promise

const promise = new Promise((resolve, reject) => {
  // 異步操作
  setTimeout(() => {
    const success = true;
    if (success) {
      resolve("操作成功");
    } else {
      reject("操作失敗");
    }
  }, 1000);
});

1.3 使用 Promise

promise
  .then((result) => {
    console.log(result); // "操作成功"
  })
  .catch((error) => {
    console.error(error); // "操作失敗"
  });

二、Promise 自帶方法

2.1 靜態(tài)方法

Promise.resolve()

創(chuàng)建一個立即解析的 Promise:

Promise.resolve("立即返回").then(console.log); // "立即返回"

Promise.reject()

創(chuàng)建一個立即拒絕的 Promise:

Promise.reject("錯誤").catch(console.error); // "錯誤"

Promise.all()

Promise.all()方法用于將多個 Promise 實例,包裝成一個新的 Promise 實例。等待所有 Promise 完成,或任意一個失敗。

“致命傷”:一個失敗,全盤皆輸

// 假設有三個異步請求:獲取用戶信息、獲取商品列表、獲取消息通知
const fetchUserInfo = fetch("/api/user");
const fetchProducts = fetch("/api/products");
const fetchNotifications = fetch("/api/notifications");

Promise.all([fetchUserInfo, fetchProducts, fetchNotifications])
  .then(([userInfo, products, notifications]) => {
    // 只有當三個請求都成功時,才會進入這里
    renderUserPage(userInfo, products, notifications);
  })
  .catch((error) => {
    // 如果任何一個請求失敗,就會跳到這里
    console.error("有一個請求失敗了:", error);
    showErrorPage("頁面加載失敗,請重試!");
  });

Promise.race()

返回最先完成的 Promise(無論成功或失敗):

const p1 = new Promise((res) => setTimeout(res, 100, "慢"));
const p2 = new Promise((res) => setTimeout(res, 50, "快"));

Promise.race([p1, p2]).then((winner) => {
  console.log(winner); // "快"
});

Promise.allSettled()

為了解決 Promise.all 一個失敗,全盤皆輸?shù)倪@個痛點,ES2020 引入了 Promise.allSettled 方法。它的行為更加寬容和穩(wěn)?。?/p>

  • 等待所有:它會等待所有輸入的 Promise 都“敲定”(settled),即無論是成功(fulfilled)還是失敗(rejected)。
  • 永不失?。?strong>Promise.allSettled 自身永遠不會被 reject,它總是會成功返回一個數(shù)組。
  • 詳情可知:返回的數(shù)組中的每個對象都包含了每個 Promise 的最終狀態(tài)和結果(或原因)。

每個結果對象都有兩種形態(tài):

  • 成功:{ status: 'fulfilled', value: 結果值 }
  • 失?。?code>{ status: 'rejected', reason: 錯誤原因 }

如何使用 Promise.allSettled:

Promise.allSettled([fetchUserInfo, fetchProducts, fetchNotifications]).then((results) => {
  // 注意:這里永遠不會 catch
  // results 是一個包含三個對象的數(shù)組
  const userInfo = results[0].status === "fulfilled" ? results[0].value : null;
  const products = results[1].status === "fulfilled" ? results[1].value : null;
  const notifications = results[2].status === "fulfilled" ? results[2].value : null; // 我們可以針對每個結果進行精細化處理

  if (userInfo && products) {
    // 只要核心數(shù)據(jù)(用戶和商品)還在,就渲染頁面
    renderUserPage(userInfo, products, notifications); // notifications 可能是 null
    if (!notifications) {
      showToast("通知獲取失敗,不影響主要功能");
    }
  } else {
    // 如果核心數(shù)據(jù)缺失,再顯示錯誤頁
    showErrorPage("核心數(shù)據(jù)加載失敗");
  }
});
// 不需要 .catch,因為它永遠不會被觸發(fā)

使用 Promise.allSettled 優(yōu)勢:

  • 體驗提升:即使通知接口掛了,用戶依然能看到頁面主體內(nèi)容,只會收到一個輕量的提示。
  • 韌性增強:單個接口的失敗不會導致整個頁面或功能的崩潰。
  • 信息完整:我們可以確切地知道每個任務的執(zhí)行結果,并據(jù)此做出更細致的 UI 響應。

Promise.any()

返回第一個成功的 Promise(忽略失?。?/p>

const p1 = Promise.reject("錯誤1");
const p2 = Promise.resolve("成功");

Promise.any([p1, p2]).then((firstSuccess) => {
  console.log(firstSuccess); // "成功"
});

2.2 實例方法

.then()

處理 Promise 的成功狀態(tài):

fetch("/api")
  .then((response) => response.json())
  .then((data) => console.log(data));

.catch()

捕獲 Promise 鏈中的錯誤:

fetch("/api")
  .then((response) => response.json())
  .catch((error) => console.error("請求失敗:", error));

.finally()

無論成功或失敗都會執(zhí)行:

fetch("/api")
  .then((response) => response.json())
  .finally(() => console.log("請求結束"));

三、Promise 高級技巧

3.1 鏈式調(diào)用

function getUser(id) {
  return fetch(`/users/${id}`)
    .then((response) => response.json())
    .then((user) => fetch(`/profile/${user.profileId}`))
    .then((response) => response.json());
}

3.2 錯誤處理策略

// 方式1:每個 then 后單獨 catch
fetch("/api")
  .then((res) => res.json())
  .catch(handleJSONError)
  .then((data) => process(data))
  .catch(handleProcessError);

// 方式2:全局 catch
fetch("/api")
  .then((res) => res.json())
  .then((data) => process(data))
  .catch(handleAnyError);

3.3 取消 Promise

原生 Promise 無法取消,但可以通過封裝實現(xiàn):

function cancellablePromise(promise) {
  let isCancelled = false;

  const wrappedPromise = new Promise((resolve, reject) => {
    promise.then((value) => !isCancelled && resolve(value)).catch((error) => !isCancelled && reject(error));
  });

  return {
    promise: wrappedPromise,
    cancel: () => {
      isCancelled = true;
    }
  };
}

3.4 Promise 化回調(diào)函數(shù)

將回調(diào)風格的函數(shù)轉(zhuǎn)換為 Promise:

const fs = require("fs");

function readFilePromise(path) {
  return new Promise((resolve, reject) => {
    fs.readFile(path, (err, data) => {
      if (err) reject(err);
      else resolve(data);
    });
  });
}

四、Promise 與 async/await

4.1 基本轉(zhuǎn)換

// Promise 風格
function getData() {
  return fetch("/api").then((res) => res.json());
}

// async/await 風格
async function getData() {
  const res = await fetch("/api");
  return res.json();
}

4.2 錯誤處理對比

// Promise
fetch("/api")
  .then((res) => res.json())
  .catch(console.error);

// async/await
try {
  const res = await fetch("/api");
  const data = await res.json();
} catch (err) {
  console.error(err);
}

五、常見問題與解決方案

5.1 Promise 內(nèi)存泄漏

未處理的 Promise 拒絕會導致內(nèi)存泄漏:

// 錯誤示范(未捕獲的拒絕)
function riskyOperation() {
  return new Promise((_, reject) => {
    setTimeout(reject, 1000, "錯誤");
  });
}

// 正確做法
riskyOperation().catch(() => {});

5.2 并行與順序執(zhí)行

// 順序執(zhí)行
async function sequential() {
  await task1();
  await task2(); // 等待 task1 完成
}

// 并行執(zhí)行
async function parallel() {
  await Promise.all([task1(), task2()]);
}

六、總結

Promise 的核心優(yōu)勢:

  1. 鏈式調(diào)用:解決回調(diào)地獄
  2. 統(tǒng)一錯誤處理:通過 .catch() 集中管理
  3. 組合能力強Promise.all/race 等實現(xiàn)復雜控制流

最佳實踐建議:

  • 始終返回 Promise 鏈(避免中斷)
  • 使用 async/await 提升可讀性
  • 不要忘記錯誤處理
// 終極實踐示例
async function getFullData() {
  try {
    const [user, posts] = await Promise.all([fetchUser(), fetchPosts()]);
    return { user, posts };
  } catch (error) {
    console.error("加載失敗:", error);
    throw error; // 向上傳遞
  }
}

常用方法的區(qū)別

方法核心邏輯成功條件失敗條件典型使用場景
Promise.all(iterable)“全部成功”
等待所有 Promise 完成
所有 Promise 都成功 (fulfilled)任意一個 Promise 失敗 (rejected)并行處理多個相互依賴的任務,如:同時上傳多張圖片、同時獲取多個 API 數(shù)據(jù)以渲染頁面。
Promise.race(iterable)“競賽”
取最先完成(無論成敗)的 Promise 結果
最先完成的 Promise 是成功 (fulfilled)最先完成的 Promise 是失敗 (rejected)1. 設置超時/競速:為異步操作添加超時限制。
2. 從多個最快響應的來源(如 CDN)獲取資源。
Promise.allSettled(iterable)“無論成敗”
等待所有 Promise 最終敲定 (settled)
總是成功
(返回每個 Promise 的最終狀態(tài)和結果數(shù)組)
不會失敗當需要知道每個異步操作的最終結果時,如:批量提交表單,無論單個成功或失敗都需要記錄日志或進行下一步處理。
Promise.any(iterable)“任一成功”
取最先成功的 Promise 結果
任意一個 Promise 成功 (fulfilled)所有 Promise 都失敗 (rejected)1. 尋找最快可用資源:從多個鏡像服務器下載同一個文件,使用最先響應的。
2. 提供備用方案,只要一個成功即可。

快速選擇指南

當你面對多個異步操作時,可以這樣選擇:

  • 需要所有操作都成功才能繼續(xù) → Promise.all()
  • 只需第一個完成的操作結果(無論成敗) → Promise.race()
  • 需要知道每個操作的最終結果(無論成?。?→ Promise.allSettled()
  • 只需第一個成功的操作結果Promise.any()

總結

到此這篇關于JavaScript中Promise講解和使用方法的文章就介紹到這了,更多相關js Promise使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

芜湖市| 凌云县| 娄烦县| 青州市| 会泽县| 化德县| 阳东县| 辰溪县| 称多县| 江川县| 黎平县| 合江县| 兰溪市| 新竹县| 贵州省| 巴林左旗| 饶阳县| 馆陶县| 盱眙县| 汉阴县| 宣恩县| 宁夏| 叶城县| 贵南县| 筠连县| 富裕县| 灵宝市| 辽宁省| 湖州市| 庄浪县| 会宁县| 稷山县| 镇赉县| 平乐县| 雅安市| 新田县| 柘城县| 通许县| 凯里市| 吴江市| 平山县|