JavaScript中的Promise用法大全(非常詳細(xì)!)
一、相關(guān)概念介紹
1.什么是Promise
在JavaScript中,Promise是一個用于進(jìn)行異步編程的構(gòu)造函數(shù)。它是ES6中引入的一個重要概念,用于處理異步操作。Promise是JavaScript中用于處理異步操作的對象,它代表了一個尚未完成但最終會完成或失敗的操作。Promise的目的是以更優(yōu)雅的方式書寫復(fù)雜的異步任務(wù),從而提高代碼的可讀性和可維護(hù)性。
2.Promise狀態(tài)
Promise對象代表一個異步操作,有三種狀態(tài):Pending(進(jìn)行中)、Resolved(已完成)和Rejected(已失敗)。
- 當(dāng)Promise被創(chuàng)建后,它的狀態(tài)是Pending。
- 當(dāng)操作成功完成,它的狀態(tài)變成fulfilled,并傳遞一個值作為成功的結(jié)果。此時,then中的用于處理成功操作的回調(diào)會被執(zhí)行。
- 當(dāng)操作失敗,它的狀態(tài)變成rejected,并傳遞失敗的原因。此時,then中的用于處理失敗操作的回調(diào)會被執(zhí)行。
3.創(chuàng)建Promise
通過構(gòu)造函數(shù)創(chuàng)建一個Promise對象,構(gòu)造函數(shù)接收一個函數(shù)作為參數(shù),該函數(shù)的兩個參數(shù)分別是resolve和reject。resolve函數(shù)的作用是將Promise對象的狀態(tài)從Pending變?yōu)镽esolved,在then方法中傳入的回調(diào)函數(shù)會被調(diào)用。reject函數(shù)的作用是將Promise對象的狀態(tài)從Pending變?yōu)镽ejected,在catch方法中傳入的回調(diào)函數(shù)會被調(diào)用。
4.then()方法
- Promise對象身上有then方法,可用來指定回調(diào),對成功和失敗的結(jié)果進(jìn)行處理。
- then() 接受兩個參數(shù),一個處理成功狀態(tài)的回調(diào),另一個是處理失敗狀態(tài)的回調(diào)。
- then()返回的是一個Promise對象,支持鏈?zhǔn)秸{(diào)用。
- then()方法中不能改變Promise的狀態(tài)。
5.catch方法
Promise對象的catch方法用于捕獲鏈中的任何一步的錯誤。
6.鏈?zhǔn)秸{(diào)用
- then()和catch都會返回Promise對象,所以可以使用鏈?zhǔn)秸{(diào)用來處理多個異步操作,解決了多層嵌套的問題。
- 可以解決異步編程回調(diào)地獄的問題。
7.異步編程
在JS中,Promise是一個代表了異步操作最終完成或失敗,及其結(jié)果值的對象。它允許開發(fā)人員為異步操作的成功和失敗情況注冊處理程序,極大地簡化了異步編程的復(fù)雜性。
二、使用
1.構(gòu)造Promise
new Promise(function(resolve,rejecrt) { //異步操作 //....... //操作成功 resolve("success"); }).then(value=>{ console.log(value); });
Promise構(gòu)造函數(shù)接受一個函數(shù)類型的參數(shù)executor,我們稱executor為執(zhí)行器函數(shù)。
2.executor 函數(shù)
- executor 函數(shù)在 Promise 構(gòu)造函數(shù)中是作為一個參數(shù)被傳入,并在 Promise 對象被創(chuàng)建后立即執(zhí)行。 executor可以是用function申明的函數(shù),也可以是箭頭函數(shù)。
- executor 函數(shù)帶有 resolve 和 reject 兩個函數(shù)類型的參數(shù) 。當(dāng)調(diào)用任意一個參數(shù)時,會改變 Promise 對象的狀態(tài)。
- 異步操作成功時,調(diào)用 resolve 函數(shù), Promise 對象的狀態(tài)就會由 pending 變?yōu)?nbsp;fulfilled(已兌現(xiàn)),并返回 executor 函數(shù)中 resolve 的參數(shù)(成功的值)。
- 異步操作失敗時,調(diào)用 reject 函數(shù), Promise 對象的狀態(tài)就會由 pending 變?yōu)閞ejected(已拒絕),并返回 executor 函數(shù)中 reject 的參數(shù)(失敗的原因)。
- executor 中拋出的任何錯誤都會導(dǎo)致 Promise 被拒絕,并且返回值將被忽略。
3.then() 方法
const p1= new Promise(function(resolve,rejecrt) { setTimeout(() => { var currentSecond = new Date().getSeconds(); //獲取當(dāng)前時間的秒數(shù),若為偶數(shù)則操作成功,否則為操作失敗 if(currentSecond%2===0) { //操作成功 resolve(currentSecond);//p1的狀態(tài)轉(zhuǎn)變成fulfilled console.log(p1); } else { rejecrt(new Error(currentSecond));//操作失敗,p1的狀態(tài)轉(zhuǎn)變成rejected console.log(p1); } }, 1000); }) p1.then(value=>{ console.log("success: "+value);//處理操作成功的情況 }) .catch(error=>{ console.error(error);//處理失敗的情況 });
由運(yùn)行結(jié)果可知:
- reject函數(shù)用于將Promise狀態(tài)轉(zhuǎn)成rejected狀態(tài),并傳遞一個原因作為失敗的結(jié)果。
- resolve函數(shù)用于將Promise狀態(tài)轉(zhuǎn)成fulfilled狀態(tài),并傳遞一個值作為成功的結(jié)果。
- Promise狀態(tài)轉(zhuǎn)成fulfilled時,執(zhí)行then方法。當(dāng)狀態(tài)轉(zhuǎn)成rejected時,被catch捕獲。
4.then() 方法返回的Promise的狀態(tài)
下面的3段代碼將討論:根據(jù)回調(diào)函數(shù)返回值的不同類型,確定then() 方法返回的Promise對象的狀態(tài)值。
第1種情況:promise操作成功,回調(diào)函數(shù)返回非Promise對象
const promise= new Promise(function(resolve,rejecrt) { //操作成功 resolve('success');//p1的狀態(tài)轉(zhuǎn)變成fulfilled }) const p1=promise.then(value=>{//接受promise成功的回調(diào) return '345678' },reason=>{}) console.log(p1);
第二種情況:promise操作失敗,回調(diào)函數(shù)返回非Promise對象
const promise= new Promise(function(resolve,rejecrt) { //失敗成功 rejecrt('fail');//p1的狀態(tài)轉(zhuǎn)變成fulfilled }) const p1=promise.then(value=>{},reason=>{ return '123456' }) console.log(p1);
promise回調(diào)函數(shù)拋出異常
const promise= new Promise(function(resolve,rejecrt) { //操作成功 resolve('success');//p1的狀態(tài)轉(zhuǎn)變成fulfilled }) const p1=promise.then(value=>{//在回調(diào)函數(shù)中拋出異常 throw '出錯了' },reason=>{}) console.log(p1);
promise回調(diào)函數(shù)返回Promise對象
const promise= new Promise(function(resolve,rejecrt) { //操作成功 resolve('success');//p1的狀態(tài)轉(zhuǎn)變成fulfilled }) const p1=promise.then(value=>{ //回調(diào)函數(shù)返回Promise對象 return new Promise((resolve,rejecrt)=>{ resolve('成功了'); }) },reason=>{}) console.log(p1);
根據(jù)上面的四種情況,我們可以得出結(jié)論如下:
- 1)promise操作成功,回調(diào)函數(shù)返回非Promise對象,p1的狀態(tài)是fulfilled
- 2)promise操作失敗,回調(diào)函數(shù)返回非Promise對象,p1的狀態(tài)是fulfilled
- 3)promise回調(diào)函數(shù)拋出異常,p1的狀態(tài)是rejected
- 4)回調(diào)函數(shù)的返回結(jié)果是promise對象,則p1的狀態(tài)就取決于return返回的這個promise對象內(nèi)部的狀態(tài),內(nèi)部為resolve, 則p1狀態(tài)為fulfilled,內(nèi)部為reject,則p1狀態(tài)為rejected
三、Async/Await語法糖
Async/Await是基于Promise的語法糖,使得異步代碼的編寫更加簡潔和易于理解。使用async關(guān)鍵字聲明異步函數(shù),await關(guān)鍵字用于在函數(shù)中等待Promise的解析。await只能在async函數(shù)內(nèi)部使用。
async function asyncFunction() { console.log("程序開始"); const promise = new Promise((resolve, reject) => { setTimeout(() => { resolve("兩秒后,耗時的任務(wù)操作成功"); }, 2000); }); const result = await promise; // 等待promise解析 console.log(result); // 輸出: Resolved } console.log(asyncFunction()); // 調(diào)用異步函數(shù) console.log('程序結(jié)束')
- async 標(biāo)記的函數(shù)是個Promise對象。
- 如果表達(dá)式是promise對象并且狀態(tài)為成功,那么await將返回的是這個promise對象成功的值。
- 如果表達(dá)式是promise對象,并且它失敗了,那么就要通過try,catch進(jìn)行捕獲錯誤,不捕獲錯誤那么后面代碼無法執(zhí)行.
四、Promise應(yīng)用場景
- 定時器:可以使用 Promise 來管理定時器操作,譬如延遲執(zhí)行某個任務(wù)或定時輪詢服務(wù)器。
- Ajax 請求:使用 Promise 可以更方便地管理 Ajax 請求。例如,在使用 Fetch API ,Axios或其他 Ajax 庫時,可以將異步操作封裝在 Promise 中,以便更好地處理成功和失敗的情況 。
- 文件操作:在文件的讀、寫或上傳等操作時,Promise 可以提供更清晰的代碼結(jié)構(gòu)和錯誤機(jī)制處理。
五、總結(jié)
Promise 是一種用于處理異步操作的 JavaScript 對象,它提供了一種更清晰、更可靠的方式來管理異步代碼。以下是 Promise 的主要特點(diǎn)和優(yōu)勢的總結(jié):
- 簡化異步操作:Promise 可以幫助我們更輕松地處理異步操作,以及在操作完成后執(zhí)行相應(yīng)的邏輯。
- 鏈?zhǔn)秸{(diào)用:鏈?zhǔn)秸{(diào)用使得多個異步任務(wù)能夠順序執(zhí)行,每個任務(wù)的輸出可以作為下一個任務(wù)的輸入。這種方式大大提高了代碼的可讀性和可維護(hù)性。與嵌套回調(diào)相比,鏈?zhǔn)秸{(diào)用避免了多層嵌套,使代碼更為扁平和直觀。
- 錯誤處理機(jī)制:如果鏈?zhǔn)秸{(diào)用中任意一個 Promise 被拒絕(rejected),后續(xù)的 then() 將會跳過,直接進(jìn)入下一個 catch()。這是 Promise 鏈中獨(dú)特的錯誤處理機(jī)制,確保開發(fā)者能夠集中處理異步操作中的錯誤。
- 異步任務(wù)的順序執(zhí)行:當(dāng)我們需要依次執(zhí)行多個異步操作時,鏈?zhǔn)秸{(diào)用可以提供非常簡潔的代碼結(jié)構(gòu)。
- 避免回調(diào)地獄::Promise 可以解決回調(diào)地獄問題,使代碼結(jié)構(gòu)更加清晰和易于理解。Promise.then返回的也是一個promise對象,因此可以進(jìn)行鏈?zhǔn)秸{(diào)用。這也是promise可以解決異步編程回調(diào)地獄的原因。
到此這篇關(guān)于JavaScript中Promise用法大全的文章就介紹到這了,更多相關(guān)JS中Promise用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js下劃線和駝峰互相轉(zhuǎn)換的實(shí)現(xiàn)(多種方法)
本文主要介紹了js下劃線和駝峰互相轉(zhuǎn)換的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10實(shí)現(xiàn)點(diǎn)擊列表彈出列表索引的兩種方式
使用利用事件冒泡委托給列表的父節(jié)點(diǎn)去處理的方式第二種方式就是使用閉包了,感興趣的你可以參考下本文,或許對你學(xué)習(xí)js有所幫助2013-03-03設(shè)置下載不需要倒計(jì)時cookie(倒計(jì)時代碼)
利用賦值downvip實(shí)現(xiàn)軟件下載的倒計(jì)時代碼2008-11-11javascript跳轉(zhuǎn)與返回和刷新頁面的實(shí)例代碼
這篇文章主要介紹了javascript跳轉(zhuǎn)與返回和刷新頁面的實(shí)例代碼,簡單介紹了javascript中window.open()與window.location.href的區(qū)別,感興趣的朋友一起看看吧2019-11-11JavaScript實(shí)現(xiàn)時間倒計(jì)時跳轉(zhuǎn)(推薦)
這篇文章主要介紹了JavaScript實(shí)現(xiàn)時間倒計(jì)時跳轉(zhuǎn)(推薦)的相關(guān)資料,涉及到settimeout和setinterval方法的介紹,非常不錯具有參考借鑒價值,需要的朋友可以參考下2016-06-06js實(shí)現(xiàn)簡潔大方的二級下拉菜單效果代碼
這篇文章主要介紹了js實(shí)現(xiàn)簡潔大方的二級下拉菜單效果代碼,涉及javascript通過鼠標(biāo)事件控制頁面元素的動態(tài)變換技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-09-09JavaScript實(shí)現(xiàn)百度搜索框效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)百度搜索框效果2018-05-05
,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下