为何Chrome扩展Background.ts脚本因Promise调用无法安装?
Chrome扩展Background脚本调用storage初始化函数后崩溃问题
问题详情
我在安装/加载/重载Chrome扩展时,尝试用Promise初始化chrome.storage.local,但调用ModelDataColdSet后Background脚本直接无法运行。使用Node 16.14.2版本,删除ModelDataColdSet(ModelDataColdDefault)这行代码后,脚本就能正常运行并打印[Background]。参考的教程都是类似实现方式,实在搞不懂哪里出问题了。
相关代码
ModelData.ts
export interface ModelData { cold?: Object } export type ModelDataKeys = keyof ModelData export const ModelDataColdDefault = {} export function ModelDataColdSet(cold: Object): Promise<void> { const values: ModelData = { cold, } return new Promise((resolve) => { chrome.storage.local.set(values, () => { resolve() }) }) } export function ModelDataColdGet(): Promise<Object> { const keys: ModelDataKeys[] = ["cold"] return new Promise((resolve) => { chrome.storage.local.get(keys, (res: ModelData) => { resolve(res.cold ?? {}) }) }) }
Background.ts
import { ModelDataColdDefault , ModelDataColdSet } from './ModelData'; console.log('[Background]'); chrome.runtime.onInstalled.addListener(() => { console.log('Initializing extension'); ModelDataColdSet(ModelDataColdDefault); chrome.alarms.create("FeedUpdate", { periodInMinutes: 1/60, }); chrome.contextMenus.create({ "id": "FeedAddSelectionContextMenu", "title": "Add selection to broadcast.", "contexts": ["selection"] }); chrome.contextMenus.create({ "id": "FeedAddPageContextMenu", "title": "Add current page to your mom." }); }); chrome.alarms.onAlarm.addListener((alarm) => { console.log('[onAlarm.FeedUpdate]'); if (alarm.name === "FeedUpdate") { console.log('[onAlarm.FeedUpdate]'); } });
问题排查与解决方法
1. 检查扩展权限
Chrome扩展使用chrome.storage.local必须在manifest.json中声明storage权限,否则API调用会直接报错导致脚本终止。同时你还用到了alarms和contextMenus,也要一并声明:
{ "manifest_version": 3, "permissions": ["storage", "alarms", "contextMenus"], // 其他manifest配置项 }
2. 完善Promise的错误处理
你的ModelDataColdSet只处理了成功回调,没有处理Chrome API调用失败的情况。当API调用出错时(比如权限不足),会产生未捕获的错误,直接终止脚本。修改函数加上错误捕获:
export function ModelDataColdSet(cold: Object): Promise<void> { const values: ModelData = { cold, }; return new Promise((resolve, reject) => { chrome.storage.local.set(values, () => { // 检查Chrome API是否返回错误 if (chrome.runtime.lastError) { reject(chrome.runtime.lastError); } else { resolve(); } }); }); }
然后在调用时也要捕获错误,避免脚本崩溃:
chrome.runtime.onInstalled.addListener(async () => { console.log('Initializing extension'); try { await ModelDataColdSet(ModelDataColdDefault); console.log('Storage initialized successfully'); } catch (error) { console.error('Failed to initialize storage:', error); } // 后续的alarms和contextMenus创建代码保持不变 });
3. (可选)优化TypeScript类型
Object类型过于宽泛,建议换成更具体的类型(比如Record<string, unknown>),提升代码健壮性,但这不是导致脚本崩溃的直接原因:
export interface ModelData { cold?: Record<string, unknown> } export const ModelDataColdDefault: Record<string, unknown> = {} export function ModelDataColdSet(cold: Record<string, unknown>): Promise<void> { // ... 函数内容不变 } export function ModelDataColdGet(): Promise<Record<string, unknown>> { // ... 函数内容不变 }
内容的提问来源于stack exchange,提问作者Cale McCollough
相关产品推荐
相关产品推荐

