Promise函式

Promise 是用來最佳化非同步的語法
而 Async、Await 可以基於 Promise 讓非同步的語法的結構類似於 “同步語言”,更易讀且好管理。
執行順序
-
開始 -
程式碼結束 -
非同步事件<- 最後執行
console.log('開始');
setTimeout(() => {
console.log('非同步事件');
}, 0);
console.log('程式碼結束');
雖然在上段的原始碼中,setTimeout 所定義的時間為 0,但因為是屬於非同步事件,因此還是會在其他原始碼執行完以後才執行。
Promise 的 用法
const myFirstPromise = new Promise((resolve, reject) => {
resolve(someValue); // 完成
reject("failure reason"); // 拒絕
});
函式
function myAsyncFunction(url) {
return new Promise((resolve, reject) => {
// resolve() or reject()
});
};
resolve 和 reject 方法是用於結束Promise並返回結果或錯誤的方法,它們是用於管理Promise的狀態的。
resolve 方法用於結束Promise並返回結果,reject 方法用於結束Promise並返回錯誤。
then 和 catch 方法是用於設定成功與失敗的回撥函式(callback functions)的方法。
then 方法接受一個函式作為引數,該函式在Promise成功時呼叫,catch 方法接受一個函式作為引數,該函式在Promise失敗時呼叫。
通俗的說,resolve 和 reject 是決定Promise的狀態,then 和 catch 是在Promise狀態確定後觸發的回撥函式。
下面就舉一個簡單的例子
const myPromise = new Promise((resolve, reject) => {
// 模拟一個異步任務
setTimeout(() => {
const randomNum = Math.random();
if (randomNum > 0.5) {
resolve("OK");
} else {
reject("NO");
}
}, 1000);
});
myPromise
.then(result => {
console.log(result);
})
.catch(error => {
console.log(error);
});
再舉一個例子
function promise() {
return new Promise((resolve, reject) => {
// 隨機取得 0 or 1
const num = Math.random() > 0.5 ? 1 : 0;
// 1 則執行 resolve,否則執行 reject
if (num) {
resolve('成功');
}
reject('失敗')
});
}
promise(1)
.then(success => {
console.log(success);
return promise(2);
})
.then(success => {
console.log(success);
return promise(0); // 這個階段會進入 catch
})
.then(success => { // 由於上一個階段結果是 reject,所以此段不執行
console.log(success);
return promise(3);
})
.catch(fail => {
console.log(fail);
})
// 假如success => promise(2) 執行第二個then => success => promise(0)
// => fail
JS async/await 系列:基礎概念篇 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天非同步在前端的做法不斷的在進行最佳化調整,先前介紹過 Promise 可以解決非同步過度巢狀的問題,而本篇要介紹的 async function(非同步函式) 及 await 則可以將非同步的程式碼寫成類似同步的形式。 Promise 本篇不會詳細介紹,如果不熟悉可以先檢視 本篇 文章,Promise 與非同步函式兩者是密不可分的,雖然 async function 易讀性優於 Promise,但請先確保對於 Promise 有一定理解再來使用非同步函式。 本篇先建立一個基於 Promise 的函式,以下的範例都會不斷呼叫此函式來進行撰寫。 /** * 範例 Promise 函式 * * @param {數值:作為判斷非同步成功與否的條件} num * @param {數值:非同步所執行的時間長度} [time=500] * @returns {如果 num 為真則套用 resolve;失敗則套用 reject} */ function promiseFn(num, time = 500) { return new Promise((resolve, reject) => { setTimeout(() => { num ? https://ithelp.ithome.com.tw/articles/10249787#:~:text=async%20function%20%E5%8F%AF%E4%BB%A5%E7%94%A8%E4%BE%86,%E5%90%8C%E6%AD%A5%E5%87%BD%E5%BC%8F%E7%9A%84%E9%81%8B%E8%A1%8C%E3%80%82
Promise 的回傳狀態,需要進入 resolve 或 reject 後,非同步函式才會繼續執行
Promise.all:
這是一個靜態方法,它接受一個 Promises 陣列作為輸入,並返回一個 Promise,在所有輸入的 Promises 都完成後結果。
示例:
javascriptCopy code
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
// 這句話是使用 JavaScript 中的 setTimeout 函數,設定了一個指定的時間(100 毫秒)後,執行 resolve 函數,並將字串 "foo" 傳給 resolve 函數。
// 因此,這個 Promise 最終會在 100 毫秒後得到解決,並傳回 "foo" 作為結果。
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
// expected output: Array [3, 42, "foo"]
Promise.race
類似於 Promise.all,但 Promise.race 只返回第一個完成的 Promise,不管是 resolve 還是 reject。
示例:
javascriptCopy code
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value);
// expected output: "two"
});
Promise.allSettled:
這是一個靜態方法,它接受一個 Promises 陣列作為輸入,並返回一個 Promise,等待所有輸入的 Promises 都完成。 不管是 resolve 還是 reject,它都會給出結果。
示例:
javascriptCopy code
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'resolved');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(reject, 100, 'rejected');
});
Promise.allSettled([promise1, promise2]).then((results) => {
console.log(results);
// [
// { status: 'fulfilled', value: 'resolved' },
// { status: 'rejected', reason: 'rejected' }
// ]
});
Promise any
方法是在 ECMAScript 2020 新增的,它接收一個 Promise 物件陣列作為引數,並返回一個 Promise 物件,該 Promise 物件將在傳入的所有 Promise 物件中的任意一個被成功執行時解決。如果傳入的所有 Promise 物件都被拒絕,則該 Promise 物件將被拒絕。
const promise1 = new Promise((resolve, reject) => setTimeout(reject, 100, 'promise1 failed'));
const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 200, 'promise2 succeeded'));
const promise3 = new Promise((resolve, reject) => setTimeout(reject, 300, 'promise3 failed'));
Promise.any([promise1, promise2, promise3])
.then(console.log)
.catch(console.error);
//在此示例中,最先成功执行的 Promise 对象是 promise2,因此该 Promise 对象的结果将被解决为 "promise2 succeeded"。