語法
Promise.try(func)
Promise.try(func, arg1)
Promise.try(func, arg1, arg2)
Promise.try(func, arg1, arg2, /* …, */ argN)
引數
func-
一個同步呼叫的函式,並附帶提供的引數(
arg1,arg2, …,argN)。它可以做任何事情——返回值、丟擲異常或返回一個 promise。 arg1,arg2, …,argN-
要傳遞給
func的引數。
返回值
一個 Promise,它
- 如果
func同步返回值,則為已解決。 - 如果
func同步丟擲異常,則為已拒絕。 - 如果
func返回一個 promise,則為非同步解決或拒絕。
描述
您可能有一個接受回撥函式的 API。該回調函式可能是同步的或非同步的。您希望透過將結果封裝在 promise 中來統一處理所有內容。最直接的方法可能是 Promise.resolve(func())。問題是,如果 func() 同步丟擲異常,該異常將不會被捕獲並轉換為已拒絕的 promise。
常見的做法(將函式呼叫的結果提升為 promise,已解決或已拒絕)通常如下所示:
new Promise((resolve) => resolve(func()));
但 Promise.try() 在這裡更有幫助
Promise.try(func);
對於內建的 Promise() 建構函式,從執行器丟擲的異常會自動捕獲並轉換為拒絕,因此這兩種方法在大多數情況下是等效的,只是 Promise.try() 更簡潔易讀。
請注意,Promise.try() 不等同於此,儘管它們非常相似。
Promise.resolve().then(func);
區別在於傳遞給 then() 的回撥函式始終是非同步呼叫的,而 Promise() 建構函式的執行器是同步呼叫的。Promise.try 也同步呼叫函式,並在可能的情況下立即解析 promise。
Promise.try() 結合 catch() 和 finally(),可以用來在單個鏈中處理同步和非同步錯誤,使 promise 的錯誤處理看起來幾乎像同步錯誤處理。
與 setTimeout() 一樣,Promise.try() 接受額外的引數,這些引數會傳遞給回撥函式。這意味著,與其這樣做
Promise.try(() => func(arg1, arg2));
您可以這樣做
Promise.try(func, arg1, arg2);
這兩者是等效的,但後者避免了建立額外的閉包,並且效率更高。
示例
使用 Promise.try()
以下示例接受一個回撥函式,“提升”它到 promise,處理結果,並進行一些錯誤處理
function doSomething(action) {
return Promise.try(action)
.then((result) => console.log(result))
.catch((error) => console.error(error))
.finally(() => console.log("Done"));
}
doSomething(() => "Sync result");
doSomething(() => {
throw new Error("Sync error");
});
doSomething(async () => "Async result");
doSomething(async () => {
throw new Error("Async error");
});
在 async/await 中,相同的程式碼將如下所示:
async function doSomething(action) {
try {
const result = await action();
console.log(result);
} catch (error) {
console.error(error);
} finally {
console.log("Done");
}
}
對非 Promise 建構函式呼叫 try()
Promise.try() 是一個通用方法。它可以被呼叫在任何實現與 Promise() 建構函式相同簽名的建構函式上。
以下是實際 Promise.try() 的一個更忠實的近似(儘管它仍然不應該用作 polyfill)
Promise.try = function (func) {
return new this((resolve, reject) => {
try {
resolve(func());
} catch (error) {
reject(error);
}
});
};
由於 Promise.try() 的實現方式(即 try...catch),我們可以安全地將 Promise.try() 的 this 設定為任何自定義建構函式,它永遠不會同步丟擲異常。
class NotPromise {
constructor(executor) {
// The "resolve" and "reject" functions behave nothing like the native
// promise's, but Promise.try() just calls resolve
executor(
(value) => console.log("Resolved", value),
(reason) => console.log("Rejected", reason),
);
}
}
const p = Promise.try.call(NotPromise, () => "hello");
// Logs: Resolved hello
const p2 = Promise.try.call(NotPromise, () => {
throw new Error("oops");
});
// Logs: Rejected Error: oops
與 Promise() 不同,這個 NotPromise() 建構函式在執行執行器時*不會*優雅地處理異常。但是,儘管有 throw,Promise.try() 仍然會捕獲異常,並將其傳遞給 reject() 進行輸出。
規範
| 規範 |
|---|
| ECMAScript® 2026 語言規範 # sec-promise.try |
瀏覽器相容性
載入中…