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

JavaScript?Promise實(shí)例方法then()、catch()、finally()詳細(xì)解析

 更新時(shí)間:2026年03月11日 09:03:25   作者:wuhen_n  
Promise是ES6引入的解決異步編程的新解決方案,語(yǔ)法上Promise是一個(gè)構(gòu)造函數(shù),用來(lái)封裝異步操作并可以獲取其成功或失敗的結(jié)果,這篇文章主要介紹了JavaScript?Promise實(shí)例方法then()、catch()、finally()的相關(guān)資料,需要的朋友可以參考下

適合有JavaScript基礎(chǔ),希望深入異步編程的開(kāi)發(fā)者。我們將用最少的篇幅,講透最核心的知識(shí)。

引言:Promise實(shí)例方法

在之前的文章中,我們探討了Promise的狀態(tài)機(jī)模型和不可變?cè)瓌t。理解了Promise的內(nèi)在狀態(tài)后,現(xiàn)在讓我們轉(zhuǎn)向它的外在行為——實(shí)例方法。如果說(shuō)狀態(tài)是Promise的"骨骼",那么實(shí)例方法就是它的"肌肉",賦予了Promise處理異步操作的能力。

我們可以把Promise就像一臺(tái)自動(dòng)咖啡機(jī)。狀態(tài)(pending、fulfilled、rejected)是它的指示燈,而then()、catch()、finally()方法就是它的操作按鈕。只有了解每個(gè)按鈕的確切功能和使用時(shí)機(jī),我們才能制作出一杯完美的"異步咖啡"。

then()方法:鏈?zhǔn)秸{(diào)用的核心

then()的基本語(yǔ)法

Then()方法是為Promise對(duì)象添加處理程序的主要方法,也是Promise中最核心、最復(fù)雜的方法。它可以接受兩個(gè)參數(shù):onResolved處理函數(shù)onRejected處理函數(shù) 。這兩個(gè)參數(shù)都是可選的,如果提供的話(huà),則會(huì)在Promise進(jìn)入 fulfilledrejected 狀態(tài)時(shí)執(zhí)行,如以下示例:

function onResolved(id) {
    console.log("resolved:" + id)
}

function onRejected(id) {
    console.log("rejected:" + id)
}

let p1 = new Promise((resolve, reject) => resolve())
let p2 = new Promise((resolve, reject) => reject())

p1.then(() => onResolved('p1'),
    () => onRejected('p1'))
p2.then(() => onResolved('p2'),
    () => onRejected('p2'))

上述代碼中,由于Promise只能轉(zhuǎn)換一次狀態(tài),所以p1和p2這兩個(gè)操作一定是互斥的,其結(jié)果為:

resolved:p1
rejected:p2

由于onResolved處理函數(shù) 和 onRejected處理函數(shù) 這兩個(gè)參數(shù)都是可選的,當(dāng)我們只想提供 onRejected處理函數(shù) 時(shí),可以在 onResolved 的位置上傳入undefined或null,這樣可以避免在內(nèi)存中創(chuàng)建多余的對(duì)象,因此then()方法在實(shí)際使用中,其傳參方式有三種:

promise.then(onFulfilled)  // 只處理成功
promise.then(null, onRejected)  // 只處理失?。ú煌扑])
promise.then(onFulfilled, onRejected)  // 同時(shí)處理成功和失敗

注:

  • then()方法中,也可以傳遞一個(gè)非函數(shù),如:promise.then(’Hello‘),但會(huì)被靜默忽略,因此不推薦這種寫(xiě)法。
  • promise.then(null, onRejected)這種寫(xiě)法也是不推薦的,因?yàn)橐话隳J(rèn)要處理成功回調(diào)。

then()的鏈?zhǔn)秸{(diào)用

Promise真正的威力來(lái)自于then()的鏈?zhǔn)秸{(diào)用能力,這不僅僅是語(yǔ)法糖,而是一種函數(shù)式編程范式的體現(xiàn)。我們來(lái)看看下面一個(gè)例子:

// 一個(gè)典型的鏈?zhǔn)秸{(diào)用示例
fetchUserData(userId)
  .then(validateUser)            // 1. 驗(yàn)證用戶(hù)數(shù)據(jù)
  .then(enrichWithProfile)       // 2. 豐富個(gè)人信息
  .then(saveToDatabase)          // 3. 保存到數(shù)據(jù)庫(kù)
  .then(notifySubscribers)       // 4. 通知訂閱者
  .then(updateCache)             // 5. 更新緩存
  .then(finalizeOperation);      // 6. 完成操作

鏈?zhǔn)秸{(diào)用的四種返回值模式

返回普通值

當(dāng)then()方法中返回一個(gè)普通值時(shí),該值會(huì)被包裝為一個(gè)新的Promise對(duì)象,如以下示例:

const myPromise = new Promise((resolve, reject) => {
    resolve('Hello');
})

myPromise.then(value => {
    console.log('收到:', value);
    return '新的普通值';  // 自動(dòng)包裝為 Promise.resolve('新的普通值')
}).then(newValue => {
    console.log('鏈?zhǔn)絺鬟f:', newValue);  // '新的普通值'
});

返回Promise

當(dāng)then()方法中返回一個(gè)Promise對(duì)象時(shí),會(huì)等待該P(yáng)romise完成后,繼續(xù)下一個(gè)then()方法的鏈?zhǔn)秸{(diào)用,如以下示例:

const myPromise = new Promise((resolve, reject) => {
    resolve('Hello')
})

myPromise.then(value => {
    return new Promise((resolve, reject) => {
        resolve(value + ' World')
    }) // 返回新的Promise
}).then(response => {
    // 等待new Promise完成
    console.log('處理后的結(jié)果:', response)  // Hello World
});

拋出異常

當(dāng)then()方法中拋出異常時(shí),會(huì)轉(zhuǎn)換為一個(gè)rejected的Promise對(duì)象,如以下示例:

const myPromise = new Promise((resolve, reject) => {
    resolve('Hello')
})

myPromise.then(value => {
    if (!value.valid) {
        throw new Error('數(shù)據(jù)無(wú)效')  // 等價(jià)于 Promise.reject(new Error('數(shù)據(jù)無(wú)效'))
    }
    return processValue(value)
}).catch(error => {
    console.log('捕獲到錯(cuò)誤:', error.message)  // '數(shù)據(jù)無(wú)效'
})

沒(méi)有返回或返回undefined

當(dāng)then()方法中沒(méi)有返回值,或返回值為undefined時(shí),會(huì)將undefined作為一個(gè)值,繼續(xù)傳遞,如以下示例:

const myPromise = new Promise((resolve, reject) => {
    resolve('Hello')
})

myPromise.then(value => {
    console.log('處理值:', value)
    // 沒(méi)有return語(yǔ)句
}).then(nextValue => {
    console.log('下一個(gè)值:', nextValue)  // undefined
})

catch()方法:錯(cuò)誤處理

catch()的本質(zhì)

Catch() 用于給Promise添加拒絕處理程序,它只接受一個(gè)參數(shù):onRejected處理函數(shù)。實(shí)際上,catch()方法是一個(gè)語(yǔ)法糖,相當(dāng)于then(null, onRejected)的語(yǔ)法,它的出現(xiàn)極大地提高了代碼的可讀性。我們來(lái)看看下面一個(gè)例子:

// 以下兩種寫(xiě)法完全等價(jià)
promise.catch(onRejected)
promise.then(null, onRejected)

// 但.catch()的可讀性更好
fetchData()
  .then(process)
  .catch(handleError)  // 清晰:這里處理錯(cuò)誤
  .then(continueAfterError)

// 對(duì)比:使用.then()的第二個(gè)參數(shù)
fetchData()
  .then(process, handleError)  // 不清晰:是處理fetch錯(cuò)誤還是process錯(cuò)誤?
  .then(continueAfterError)

錯(cuò)誤傳播機(jī)制

Promise的錯(cuò)誤處理遵循冒泡原則:錯(cuò)誤會(huì)沿著Promise鏈向后傳遞,直到被捕獲,如以下示例:

// 錯(cuò)誤傳播示例
Promise.resolve()
    .then(() => {
        console.log('步驟1: 成功')
        return '第一步結(jié)果'
    })
    .then(result => {
        console.log('步驟2: 收到', result)
        throw new Error('步驟2發(fā)生錯(cuò)誤')  // 拋出錯(cuò)誤
    })
    .then(result => {
        console.log('步驟3: 這行不會(huì)執(zhí)行')  // 被跳過(guò)
        return '第三步結(jié)果';
    })
    .catch(error => {
        console.log('捕獲到錯(cuò)誤:', error.message)  // '步驟2發(fā)生錯(cuò)誤'
        return '從錯(cuò)誤中恢復(fù)';
    })
    .then(recovery => {
        console.log('恢復(fù)后繼續(xù):', recovery)  // '從錯(cuò)誤中恢復(fù)'
    });

finally()方法:資源清理

finally()方法的獨(dú)特性

Finally()方法用于給Promise實(shí)例添加 onFinally處理程序,這個(gè)方法可以避免onResolved處理函數(shù) 和 onRejected處理函數(shù) 中出現(xiàn)冗余代碼,無(wú)論P(yáng)romise狀態(tài)為 fulfilledrejected 的都會(huì)執(zhí)行,即無(wú)論P(yáng)romise是成功還是失敗,它都會(huì)執(zhí)行。我們來(lái)看看下面的例子:

// .finally()的基本使用
fetchData()
    .then(data => {
        console.log('數(shù)據(jù)處理:', data);
        return process(data);
    })
    .catch(error => {
        console.error('處理失敗:', error);
        throw error; // 重新拋出,讓外部知道失敗
    })
    .finally(() => {
        console.log('清理資源');  // 無(wú)論成功失敗都會(huì)執(zhí)行
        cleanupResources();
    });

finally()方法的三個(gè)特性

不接受參數(shù)

promise.finally(() => {
    // 這里無(wú)法訪問(wèn)Promise的結(jié)果或錯(cuò)誤原因
    console.log('執(zhí)行清理')
})

原樣傳遞上游的結(jié)果或錯(cuò)誤

Promise.resolve('成功數(shù)據(jù)')
    .finally(() => {
        console.log('finally執(zhí)行');
        // 這里返回的值不會(huì)影響鏈的傳遞
        return 'finally的返回值會(huì)被忽略';
    })
    .then(value => {
        console.log('收到:', value);  // '成功數(shù)據(jù)',不是'finally的返回值'
    })

如果finally拋出錯(cuò)誤,會(huì)覆蓋之前的錯(cuò)誤

Promise.resolve('原始數(shù)據(jù)')
    .finally(() => {
        throw new Error('finally中的錯(cuò)誤');  // 這個(gè)錯(cuò)誤會(huì)覆蓋之前的結(jié)果
    })
    .then(value => {
        console.log('這不會(huì)執(zhí)行');  // 被跳過(guò)
    })
    .catch(error => {
        console.log('捕獲的錯(cuò)誤:', error.message);  // 'finally中的錯(cuò)誤'
    });

總結(jié)

方法對(duì)比總結(jié)

方法主要用途返回值影響執(zhí)行時(shí)機(jī)最佳實(shí)踐
then()處理成功結(jié)果,鏈?zhǔn)絺鬟f決定下一環(huán)的輸入前一個(gè)Promise完成后保持純函數(shù),明確返回值
catch()錯(cuò)誤捕獲和恢復(fù)可恢復(fù)錯(cuò)誤或重新拋出鏈中任何錯(cuò)誤發(fā)生時(shí)在適當(dāng)層級(jí)處理,不要過(guò)早吞沒(méi)錯(cuò)誤
finally()資源清理和狀態(tài)重置不影響結(jié)果傳遞無(wú)論如何都會(huì)執(zhí)行只做清理,不返回業(yè)務(wù)數(shù)據(jù)

黃金法則

  • 單一職責(zé)原則:每個(gè)then()應(yīng)該只做一件事。
  • 錯(cuò)誤早拋,晚處理:讓錯(cuò)誤傳播到合適的處理層。
  • finally()只清理:不要在finally中返回業(yè)務(wù)邏輯數(shù)據(jù)。
  • 保持鏈的可讀性:合理拆分長(zhǎng)鏈,使用命名函數(shù)。
  • 考慮可維護(hù)性:為復(fù)雜的鏈添加注釋和文檔。

結(jié)語(yǔ)

本文主要介紹了Promise的三種實(shí)例化方法,對(duì)于文章中錯(cuò)誤的地方或者有任何問(wèn)題!

到此這篇關(guān)于JavaScript Promise實(shí)例方法then()、catch()、finally()的文章就介紹到這了,更多相關(guān)Promise實(shí)例方法then()、catch()、finally()內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

磴口县| 深泽县| 社会| 读书| 渝北区| 华安县| 启东市| 财经| 泗阳县| 台东市| 阜城县| 达州市| 汤原县| 苍梧县| 西城区| 慈溪市| 达拉特旗| 穆棱市| 阳泉市| 沧州市| 徐州市| 新邵县| 蒙自县| 乌恰县| 惠来县| 揭东县| 蒲城县| 会东县| 梁平县| 绥阳县| 芜湖县| 阳曲县| 四川省| 河津市| 石嘴山市| 阜平县| 叶城县| 利津县| 广水市| 安庆市| 武鸣县|