Js的 Promise的 then catch 筆記240222
基本用法
new Promise(f=>{setTimeout(ev=>{f("一秒后輸出控制臺");},1000);
}).then(f的參數=>{console.log(f的參數);
});
// 控制臺輸出: 一秒后輸出控制臺
上面代碼中, f
的標準名叫做 resolve
, 所以應該寫成
new Promise(resolve=>{setTimeout(ev=>{resolve("一秒后輸出控制臺");},1000);
}).then(傳入resolve的參數=>{console.log(傳入resolve的參數);
});
// 控制臺輸出: 一秒后輸出控制臺
實際上Promise
和then
都可以有兩個參數, resolve
和 reject
new Promise((resolve,reject)=>{setTimeout(ev=>{resolve("傳入resolve的參數"); //執行了resolve就不會執行rejectreject("傳入reject的參數"); //執行了reject就不會執行resolve},1000);
}).then(傳入resolve的參數=>{console.log(傳入resolve的參數);
}, 傳入reject的參數=>{console.log(傳入reject的參數);
});
// 控制臺輸出: 傳入resolve的參數
雖然Promise
中的resolve
和reject
都會執行,
但then
參中的resolve
和reject
只會執行其中一個, 前面的執行了,后面就不執行了,
將resolve
和reject
調換位置測試
new Promise((resolve,reject)=>{setTimeout(ev=>{reject("傳入reject的參數"); //執行了reject就不會執行resolveresolve("傳入resolve的參數"); //執行了resolve就不會執行reject},2000);
}).then(傳入resolve的參數=>{console.log(傳入resolve的參數);
}, 傳入reject的參數=>{console.log(傳入reject的參數);
});
// 控制臺輸出: 傳入reject的參數
可以將resolve
和reject
分別寫到try{}cattch(e){}
中
new Promise((resolve,reject)=>{setTimeout(ev=>{try{resolve("傳入resolve的參數"); //執行了resolve就不會執行reject}catch(e){reject("傳入reject的參數"); //執行了reject就不會執行resolve}},1000);
}).then(傳入resolve的參數=>{console.log(傳入resolve的參數);
}, 傳入reject的參數=>{console.log(傳入reject的參數);
});
// 控制臺輸出: 傳入resolve的參數
這樣正常執行resolve, 異常執行reject .
但如果在then塊中拋異常了怎么辦呢? 可以寫到catch
函數中, 注意是catch
函數,不是trycatch
塊.
下面模擬then
中拋異常
new Promise((resolve,reject)=>{setTimeout(ev=>{try{resolve("傳入resolve的參數"); //執行了resolve就不會執行reject}catch(e){console.log(e);reject("傳入reject的參數"); //執行了reject就不會執行resolve}},3000);
}).then(傳入resolve的參數=>{console.log(傳入resolve的參數); throw "then參1函數拋異常";
}, 傳入reject的參數=>{console.log(傳入reject的參數); throw "then參2函數拋異常";
}).catch(err=>{console.log(err);
});
// 控制臺輸出:
傳入resolve的參數
then參1函數拋異常
catch
對then
兩個參數函數的異常都能捕捉,反正只會執行其中一個.
下面模擬在resolve
前出現異常
new Promise((resolve,reject)=>{setTimeout(ev=>{try{throw "resolve之前出現了異常"resolve("傳入resolve的參數"); //執行了resolve就不會執行reject}catch(e){console.log(e);reject("傳入reject的參數"); //執行了reject就不會執行resolve}},4000);
}).then(傳入resolve的參數=>{console.log(傳入resolve的參數); throw "then參1函數拋異常";
}, 傳入reject的參數=>{console.log(傳入reject的參數); throw "then參2函數拋異常";
}).catch(err=>{console.log(err);
});
// 控制臺輸出:
resolve之前出現了異常
傳入reject的參數
then參2函數拋異常
可以在then
中return
返回新的Promise
, 就可以再次調用then
, 稱為then
的鏈式調用.
new Promise((resolve,reject)=>{setTimeout(ev=>{try{resolve("傳入resolve的參數"); //執行了resolve就不會執行reject}catch(e){console.log(e);reject("傳入reject的參數"); //執行了reject就不會執行resolve}},4500);
}).then(傳入resolve的參數=>{console.log(傳入resolve的參數); return new Promise(resolve2=>resolve2("傳入resolve2的參數"))
}, 傳入reject的參數=>{console.log(傳入reject的參數); throw "then參2函數拋異常";
}).catch(err=>{console.log(err);
}).then(傳入resolve2的參數=>{console.log(傳入resolve2的參數); throw "第二個then參1函數拋異常";
}).catch(err=>{console.log(err);
});
// 控制臺輸出:
傳入resolve的參數
傳入resolve2的參數
第二個then參1函數拋異常
- 可以
then().then().then()...
- 也可以
then().catch().then().catch().then().catch()...
then中 簡寫 new Promise
上面的 return new Promise(resolve2=>resolve2("傳入resolve2的參數"))
可簡寫為 return Promise.resolve("傳入resolve2的參數");
甚至可簡寫為 return "傳入resolve2的參數";
then中的
return new Promise(resolve2=>resolve2("傳入resolve2的參數"))
可簡寫為
return Promise.resolve("傳入resolve2的參數");
甚至可簡寫為
return "傳入resolve2的參數";
new Promise((resolve,reject)=>{setTimeout(ev=>{try{resolve("傳入resolve的參數"); //執行了resolve就不會執行reject}catch(e){console.log(e);reject("傳入reject的參數"); //執行了reject就不會執行resolve}},4500);
}).then(傳入resolve的參數=>{console.log(傳入resolve的參數); return new Promise(resolve2=>resolve2("傳入resolve2的參數"))
}, 傳入reject的參數=>{console.log(傳入reject的參數); throw "then參2函數拋異常";
}).catch(err=>{console.log(err);
}).then(傳入resolve2的參數=>{console.log(傳入resolve2的參數); throw "第二個then參1函數拋異常";
}).catch(err=>{console.log(err);
});// then鏈式調用簡寫, then中的 new Promise 簡寫new Promise((resolve,reject)=>{setTimeout(ev=>{try{resolve("傳入resolve的參數"); //執行了resolve就不會執行reject}catch(e){console.log(e);reject("傳入reject的參數"); //執行了reject就不會執行resolve}},4600);
}).then(傳入resolve的參數=>{console.log(傳入resolve的參數); return Promise.resolve("傳入resolve2的參數");
}, 傳入reject的參數=>{console.log(傳入reject的參數); throw "then參2函數拋異常";
}).catch(err=>{console.log(err);
}).then(傳入resolve2的參數=>{console.log(傳入resolve2的參數); throw "第二個then參1函數拋異常";
}).catch(err=>{console.log(err);
});new Promise((resolve,reject)=>{setTimeout(ev=>{try{resolve("傳入resolve的參數"); //執行了resolve就不會執行reject}catch(e){console.log(e);reject("傳入reject的參數"); //執行了reject就不會執行resolve}},4700);
}).then(傳入resolve的參數=>{console.log(傳入resolve的參數); return "傳入resolve2的參數";
}, 傳入reject的參數=>{console.log(傳入reject的參數); throw "then參2函數拋異常";
}).catch(err=>{console.log(err);
}).then(傳入resolve2的參數=>{console.log(傳入resolve2的參數); throw "第二個then參1函數拋異常";
}).catch(err=>{console.log(err);
});
其它參考
Promise - JavaScript | MDN
Promise() 構造函數- JavaScript | MDN
使用Promise - JavaScript | MDN
Promise 是 JavaScript 中用于處理異步操作的對象,它代表了某個最終可能完成或失敗的操作及其結果值的狀態。Promise 可以幫助你組織和處理異步代碼,使得它更加容易理解和維護。
Promise 有三種狀態:
- Pending(等待中):初始狀態,既不是成功,也不是失敗。
- Fulfilled(已實現):意味著操作成功完成。
- Rejected(已拒絕):意味著操作失敗。
Promise 的基本用法如下:
- 創建一個新的 Promise 對象:
const promise = new Promise((resolve, reject) => {// 異步操作// 如果成功,調用 resolve() 并傳入結果值// 如果失敗,調用 reject() 并傳入錯誤原因或 Error 對象
});
在上面的代碼中,我們傳遞了一個函數給 Promise 構造函數,這個函數接收兩個參數:resolve
和 reject
,它們是兩個函數,由 JavaScript 引擎提供,不需要自己部署。
- 使用
.then()
方法處理 Promise:
當 Promise 的狀態變為 Fulfilled 時,會調用 .then()
方法中指定的回調函數,并傳入 Promise 的結果值。你可以在這個回調函數中處理 Promise 成功完成后的邏輯。
promise.then(result => {console.log(result); // 處理 Promise 成功后的結果
});
- 使用
.catch()
方法處理 Promise:
當 Promise 的狀態變為 Rejected 時,會調用 .catch()
方法中指定的回調函數,并傳入 Promise 的錯誤原因。你可以在這個回調函數中處理 Promise 失敗后的邏輯。
promise.catch(error => {console.error(error); // 處理 Promise 失敗后的錯誤
});
另外,你還可以使用 .finally()
方法來處理無論 Promise 成功還是失敗都需要執行的邏輯。這個方法在 Promise 狀態改變后會被調用,無論狀態是 Fulfilled 還是 Rejected。
下面是一個完整的 Promise 示例:
const promise = new Promise((resolve, reject) => {setTimeout(() => {const success = true; // 假設這是一個異步操作的結果if (success) {resolve('操作成功!'); // 當操作成功時,調用 resolve() 并傳入結果值} else {reject('操作失敗!'); // 當操作失敗時,調用 reject() 并傳入錯誤原因}}, 1000); // 模擬異步操作,延遲 1 秒后執行
});promise.then(result => {console.log(result); // 輸出:操作成功!}).catch(error => {console.error(error); // 如果操作失敗,會輸出:操作失敗!}).finally(() => {console.log('Promise 已處理完畢。'); // 無論成功還是失敗,都會輸出這句話。});
JavaScript的Promise是一種用于處理異步操作的對象。它將異步操作的結果以同步的方式進行處理,使得代碼更加清晰和易于維護。
-
Promise的基本概念:
- Promise是一個對象,它代表了一個異步操作的最終完成或失敗的結果。
- Promise有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗)。
- Promise的狀態一旦改變,就不會再變。
-
Promise的基本用法:
- 創建Promise對象:使用Promise構造函數來創建一個Promise對象,構造函數接受一個執行器函數作為參數。
- 執行器函數:執行器函數接受兩個參數,分別是resolve和reject。在異步操作完成時,調用resolve函數將Promise的狀態改為fulfilled;在異步操作失敗時,調用reject函數將Promise的狀態改為rejected。
- 處理Promise的結果:可以使用then方法來處理Promise的結果,then方法接受兩個回調函數作為參數,分別是在Promise狀態變為fulfilled時調用的回調函數和在Promise狀態變為rejected時調用的回調函數。
-
Promise的鏈式調用:
- then方法可以返回一個新的Promise對象,使得多個異步操作可以按照順序執行。
- 可以通過在then方法中返回一個新的Promise對象來實現鏈式調用。
- 可以使用catch方法來捕獲Promise鏈中的錯誤。
下面是一個使用Promise的示例代碼:
function getData() {return new Promise((resolve, reject) => {// 異步操作,例如發送Ajax請求setTimeout(() => {const data = '這是從服務器獲取的數據';resolve(data);}, 2000);});
}getData().then((data) => {console.log('成功獲取數據:', data);return data.toUpperCase();}).then((upperCaseData) => {console.log('轉換為大寫:', upperCaseData);}).catch((error) => {console.error('獲取數據失敗:', error);});