你又遇到了一個非常經典的非同步 (asynchronous) 問題!這和之前 chrome.alarms.get() 的情況是完全一樣的。
簡單的答案是:你的變數 isearly 的值不是一個 int (整數),而是一個 Promise 物件。
錯誤的根本原因
讓我們一步步分解你的程式碼,看看它實際上做了什麼:
chrome.storage.local.get(['isearly'])
這行程式碼被執行。它是一個非同步操作,意思是它會去背景讀取資料,但不會停下來等待結果。
它立即回傳一個 Promise 物件。這個 Promise 物件可以看作是一個「取貨單」,它承諾「我稍後會把資料給你」。
.then(...) 和 .catch(...)
你把取貨單(Promise)交給了 .then() 和 .catch()。這相當於告訴程式:「等貨到了(操作成功),就執行 .then() 裡面的程式碼;如果送貨出錯(操作失敗),就執行 .catch() 裡面的程式碼。」
const isearly = ...
你的變數 isearly 被賦予的值,是整個 Promise 鏈(get(...).then(...).catch(...))的最終回傳值。
一個 Promise 鏈本身回傳的仍然是一個 Promise!
結論:你的程式碼執行完畢後,isearly 變數裡面裝的是一個 Promise 物件,而不是你期望的數字 0 或 parseInt(result.isearly)。
比喻:
你去餐廳點餐(chrome.storage.local.get),服務生給了你一個取餐的號碼牌 (Promise)。你不能直接把這個號碼牌吃掉。你必須等待叫到你的號碼時(.then() 被執行),才能拿到真正的餐點(result)。
你的程式碼相當於把號碼牌存到了 isearly 變數裡。
如何修正
解決方案和之前一樣:你需要把「使用 isearly 這個值」的程式碼,放到一個能夠等待 Promise 完成的地方。
方法一:使用 async/await (最推薦,最清晰)
這是處理非同步操作最現代、最易讀的方式。你需要將你的邏輯包在一個 async 函式中。
async function getEarlySetting() {
try {
const result = await chrome.storage.local.get(['isearly']);
if (result && result.isearly) {
return parseInt(result.isearly);
} else {
return 0;
}
} catch (error) {
showMessage({ name: '發生錯誤!錯誤訊息請看控制台。', delay: 10, type: 'error' });
console.error("Error retrieving data:", error);
return 0;
}
}
async function mainLogic() {
const isearly = await getEarlySetting();
console.log(`提前通知的時間是: ${isearly} 分鐘`);
console.log(typeof isearly);
}
mainLogic();
方法二:繼續使用 .then() (將後續操作放進去)
如果你不想使用 async/await,那麼你必須接受一個事實:所有需要用到 isearly 值的程式碼,都必須被放在 .then() 的回呼函式裡面。
function initialize() { chrome.storage.local.get(['isearly']).then((result) => {
let isearly = 0;
if (result && result.isearly) {
isearly = parseInt(result.isearly);
}
console.log(`提前通知的時間是: ${isearly} 分鐘`);
console.log(typeof isearly);
setupNotifications(isearly);
}).catch((error) => {
showMessage({ name: '發生錯誤!錯誤訊息請看控制台。', delay: 10, type: 'error' });
console.error("Error retrieving data:", error);
const isearly = 0;
setupNotifications(isearly);
});
}
function setupNotifications(earlyMinutes) {
console.log(`正在根據 ${earlyMinutes} 分鐘的設定來初始化通知。`);
}
initialize();
總結
你的錯誤:試圖將一個 Promise (一個承諾/號碼牌) 當作一個 number (一個實際的值) 來使用。
解決方案:必須使用 await 或將程式碼移入 .then() 來等待承諾兌現,拿到實際的值之後,再進行後續操作。
留言
張貼留言