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

JavaScript?Promise錯誤處理與最佳實踐

 更新時間:2025年09月23日 14:52:35   作者:風茫  
Promise是ES6異步編程解決方案,解決回調(diào)地獄問題,支持鏈式調(diào)用、統(tǒng)一錯誤處理,是現(xiàn)代JavaScript異步處理的基石,本文給大家介紹JavaScript Promise錯誤處理與最佳實踐,感興趣的朋友一起看看吧

一句話概括
Promise 是 ES6 引入的異步編程解決方案,用于表示一個異步操作的最終完成或失敗,以及其返回的值。它解決了“回調(diào)地獄”(Callback Hell)問題,使異步代碼更清晰、可讀、可維護。

一、為什么需要Promise?(歷史背景)

Promise 出現(xiàn)之前,JavaScript 主要通過 回調(diào)函數(shù)(Callback) 處理異步操作:

// 回調(diào)地獄(Callback Hell)
doTask1((err, result1) => {
  if (err) return handleError(err);
  doTask2(result1, (err, result2) => {
    if (err) return handleError(err);
    doTask3(result2, (err, result3) => {
      if (err) return handleError(err);
      console.log('完成:', result3);
    });
  });
});

回調(diào)函數(shù)的痛點:

  • 嵌套層級深,難以閱讀
  • 錯誤處理重復
  • 無法 returnthrow
  • 控制流復雜(并行、串行、競態(tài)等)

Promise 的出現(xiàn)就是為了解決這些問題。

二、Promise的三種狀態(tài)(States)

Promise 對象有且僅有三種狀態(tài),一旦改變不可逆

狀態(tài)說明
pending初始狀態(tài),進行中
fulfilled成功狀態(tài),操作成功完成
rejected失敗狀態(tài),操作失敗
const promise = new Promise((resolve, reject) => {
  // 初始狀態(tài):pending
  if (success) {
    resolve(value);  // → fulfilled
  } else {
    reject(error);   // → rejected
  }
});

三、Promise構造函數(shù)

new Promise(executor)
  • executor 是一個函數(shù),格式:(resolve, reject) => {}
  • resolve(value):將 Promise 狀態(tài)變?yōu)?fulfilled
  • reject(error):將 Promise 狀態(tài)變?yōu)?rejected
  • executor立即執(zhí)行
const p = new Promise((resolve, reject) => {
  setTimeout(() => {
    Math.random() > 0.5 ? resolve('成功') : reject('失敗');
  }, 1000);
});

resolve不同值的區(qū)別

  1. 普通值或者對象,那么這個值會作為then回調(diào)的參數(shù)
  2. 另外一個Promise對象,那么這個新Promise會決定原來Promise的狀態(tài)
  3. thenable對象:這對象中有實現(xiàn)then方法,那么就會執(zhí)行該then方法,并且根據(jù)then方法的結果來決定Promise的狀態(tài)
const p = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1);
  }, 3000);
});
const promise = new Promise((resolve, reject) => {
  // 1. 普通值
  // resolve(1);
  // resolve([
  //   {
  //     name: "風茫",
  //     age: 18,
  //   },
  //   {
  //     name: "fengmang",
  //     age: 30,
  //   },
  // ]);
  // 2. resolve(promise)
  // 如果resolve的值為Promise對象,那么當前的Promise的狀態(tài)由傳入的promise來決定
  // resolve(p);
  // 3. resolve(thenable對象)
  // thenable對象: 對象有then方法,那么就會執(zhí)行then方法,并且根據(jù)then方法的結果來決定Promise的狀態(tài)
  resolve({
    name: "風茫",
    then: function (resolve, reject) {
      Math.random() > 0.5 ? resolve(100) : reject("失敗");
    },
  });
});
promise
  .then((res) => {
    console.log("res :>> ", res);
  })
  .catch((err) => {
    console.log(err);
  });

四、Promise的核心方法

1..then(onFulfilled, onRejected)

注冊成功和失敗的回調(diào)。

p.then(
  (value) => { console.log(value); },      // fulfilled
  (error) => { console.error(error); }     // rejected
);

鏈式調(diào)用的關鍵:.then() 返回一個新的 Promise

then方法返回值

const promise = new Promise((resolve, reject) => {
  resolve("aaa");
});
const p2 = promise
  .then((res) => {
    console.log(res);
    return "bbb";
  })
  .then((res) => {
    console.log(res);
    return "ccc";
  });
p2.then((res) => {
  console.log(res);
}).catch((err) => {
  console.log(err);
});
/**
 * 輸出結果:
 * aaa
 * bbb
 * ccc 
 */

解釋

  1. Promise的 then方法是返回一個新的Promise,這個新Promise的決議是等到then方法傳入的回調(diào)函數(shù) 有返回值 時進行決議
  2. 若是上一個then方法沒有使用return返回,則下一個then方法接收到的值是undefined
  3. 若是在then方法中return一個新的Promise,則下一個then方法需要等到新Promise決議之后才會執(zhí)行,將新的Promise決議結果返回給下一個then方法并執(zhí)行then方法

2..catch(onRejected)

捕獲錯誤,相當于 .then(null, onRejected)

p.catch(err => {
  console.error('出錯了:', err);
});

推薦寫法:鏈式 .then().catch(),統(tǒng)一錯誤處理

fetch('/api/data')
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.error('請求失敗:', err));

3..finally(onFinally)

無論成功或失敗都會執(zhí)行,常用于清理資源。

p.finally(() => {
  console.log('請求完成,關閉 loading...');
});

不接收參數(shù),不改變結果,常用于加載狀態(tài)、資源釋放。

五、Promise靜態(tài)方法

1.Promise.resolve(value)

作用:返回一個 fulfilled 的 Promise。

Promise.resolve(42).then(x => console.log(x)); // 42

等價于:

new Promise(resolve => resolve(42));

使用場景

  • 將值包裝為Promise:如果你有一個立即可用的值,但是你希望以 Promise 的形式來處理它(比如為了保持接口的一致性),你可以使用 Promise.resolve() 來將這個值包裝成一個已解決的 Promise。
let promise = Promise.resolve(42);
promise.then(function(value) {
 console.log(value); // 輸出: 42
});
  • 處理未知的返回值:當你不確定某個函數(shù)會返回一個普通值還是一個 Promise,但你希望統(tǒng)一用 then 方法來處理時,可以使用 Promise.resolve() 來包裹該返回值。
function maybeAsync() {
  if (/* some condition */) {
    return new Promise(/* ... */);
  } else {
    return 'immediate value';
  }
}
Promise.resolve(maybeAsync()).then(function(result) {
  console.log(result);
});
  • 模擬異步行為:有時候,即使數(shù)據(jù)已經(jīng)準備好了,你也可能想要通過 Promise.resolve() 來“延遲”執(zhí)行某些代碼,以便于和其他異步操作保持一致的流程控制。
Promise.resolve().then(() => {
  console.log('This runs after the current call stack is cleared.');
});
  • Promise 鏈條的開始:在構建一個由多個步驟組成的 Promise 鏈時,如果沒有初始的 Promise 可供鏈式調(diào)用 .then().catch() 方法,可以使用 Promise.resolve() 作為起點。
 Promise.resolve()
     .then(() => console.log('First step'))
     .then(() => console.log('Second step'));

2.Promise.reject(reason)

返回一個 rejected 的 Promise。

Promise.reject('出錯了').catch(err => console.log(err));

3.Promise.all(iterable)

作用:接收一個可迭代對象(通常是數(shù)組),其中每個元素都是一個 Promise,并發(fā)執(zhí)行多個 Promise,返回一個新的Promise。全部成功才成功,任一失敗則整體失敗

const p1 = Promise.resolve('A');
const p2 = Promise.resolve('B');
const p3 = Promise.reject('C');
Promise.all([p1, p2]).then(results => {
  console.log(results); // ['A', 'B']
});
Promise.all([p1, p2, p3]).catch(err => {
  console.log(err); // 'C'
});

適用于“所有請求都必須成功”的場景(如批量上傳)。

4.Promise.race(iterable)

返回第一個完成的 Promise(無論是成功還是失?。?/p>

const slow = new Promise(r => setTimeout(() => r('慢'), 2000));
const fast = new Promise(r => setTimeout(() => r('快'), 500));
Promise.race([slow, fast]).then(result => {
  console.log(result); // '快'
});

適用于“超時控制”:

function timeout(promise, ms) {
  const timeout = new Promise((_, reject) =>
    setTimeout(() => reject(new Error('超時')), ms)
  );
  return Promise.race([promise, timeout]);
}

5.Promise.allSettled(iterable)

等待所有 Promise 結束,無論成功或失敗,返回結果數(shù)組。

Promise.allSettled([p1, p2, p3]).then(results => {
  results.forEach((result, i) => {
    if (result.status === 'fulfilled') {
      console.log(`p${i+1} 成功:`, result.value);
    } else {
      console.log(`p${i+1} 失敗:`, result.reason);
    }
  });
});

適用于“不關心成敗,只想知道所有結果”的場景。

6.Promise.any(iterable)

返回第一個成功的 Promise;如果全部失敗,則拋出 AggregateError

const fail1 = Promise.reject('錯誤1');
const fail2 = Promise.reject('錯誤2');
const success = Promise.resolve('成功');
Promise.any([fail1, fail2, success]).then(res => {
  console.log(res); // '成功'
});

適用于“只要有一個成功即可”的場景(如多源請求)。

六、Promise的執(zhí)行機制(微任務)

Promise 的回調(diào)(.then.catch)屬于 微任務(microtask),在當前宏任務結束后立即執(zhí)行。

console.log(1);
Promise.resolve().then(() => {
  console.log(2);
});
console.log(3);
// 輸出:1 → 3 → 2

微任務優(yōu)先級高于 setTimeout(宏任務)

setTimeout(() => console.log(1), 0);
Promise.resolve().then(() => console.log(2));
console.log(3);
// 輸出:3 → 2 → 1

七、錯誤處理最佳實踐

正確方式:使用.catch()

fetch('/api')
  .then(res => res.json())
  .then(data => { throw new Error('處理失敗'); })
  .catch(err => console.error(err)); // 能捕獲

錯誤方式:在.then中不處理錯誤

fetch('/api')
  .then(res => res.json(), err => console.error(err)) // 只能捕獲 fetch 失敗
  .then(data => { throw new Error('處理失敗'); })     // 這個錯誤沒被捕獲!

建議:鏈式調(diào)用末尾加 .catch()

八、Promise的常見模式

1. 串行執(zhí)行(鏈式調(diào)用)

function asyncTask(name) {
  return Promise.resolve().then(() => {
    console.log(`執(zhí)行 ${name}`);
    return name;
  });
}
asyncTask('A')
  .then(() => asyncTask('B'))
  .then(() => asyncTask('C'));

2. 并行執(zhí)行

Promise.all([
  asyncTask('A'),
  asyncTask('B'),
  asyncTask('C')
]).then(results => console.log('全部完成'));

3. 重試機制

function retry(fn, times = 3) {
  return fn().catch(err => {
    if (times <= 1) throw err;
    return retry(fn, times - 1);
  });
}
retry(() => fetch('/api')).catch(console.error);

九、Promise的局限性

問題說明
無法取消一旦創(chuàng)建,無法中途取消
錯誤冒泡未捕獲的錯誤可能靜默失?。∟ode.js 會警告)
無法獲取進度只有成功/失敗,不支持 onProgress
冗長的 .then復雜邏輯仍難讀

解決方案:使用 async/await(ES2017)

async function getData() {
  try {
    const res = await fetch('/api');
    const data = await res.json();
    return data;
  } catch (err) {
    console.error('請求失敗:', err);
  }
}

十、總結

項目說明
定位異步編程的標準化解決方案
核心價值解決回調(diào)地獄,提供鏈式調(diào)用和統(tǒng)一錯誤處理
關鍵方法.then()、.catch().finally()
靜態(tài)方法all、race、allSettled、any、resolve、reject
執(zhí)行機制回調(diào)屬于微任務,優(yōu)先級高
現(xiàn)代替代async/await(基于 Promise

最終結論
Promise 是現(xiàn)代 JavaScript 異步編程的基石。即使你使用 async/await,其底層仍是 Promise。掌握 Promise 是成為合格前端/Node.js 開發(fā)者的必經(jīng)之路。

到此這篇關于JavaScript Promise錯誤處理與最佳實踐的文章就介紹到這了,更多相關js promise內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

闽侯县| 彝良县| 陆良县| 阆中市| 华宁县| 二连浩特市| 岳普湖县| 汉寿县| 南皮县| 上饶市| 梁平县| 台中县| 元江| 铜山县| 扎兰屯市| 镇巴县| 浦县| 红安县| 鹤壁市| 洪泽县| 榆中县| 金川县| 建瓯市| 绥滨县| 民乐县| 华坪县| 阿鲁科尔沁旗| 藁城市| 安乡县| 怀柔区| 新乡县| 渭源县| 乐至县| 禹州市| 斗六市| 普陀区| 汉寿县| 普兰县| 肇州县| 修武县| 绵阳市|