Chrome扩展MV3中chrome.scripting.executeScript回调赋值后属性读取undefined问题
问题原因
chrome.scripting.executeScript是异步API,调用后不会阻塞后续代码执行。你的第29、30行代码运行时,executeScript的回调函数还未被触发,实例的title属性还没有被赋值。- 回调函数的
this指向错误。你直接传入普通函数作为回调,此时函数内部的this并不指向Action构造函数的实例,你赋值的this.title根本没有挂载到你创建的action实例上,哪怕回调执行完成,你也无法从action实例上读到对应值。
修复方案
我们可以通过Promise+async/await处理异步逻辑,同时修正this指向问题,修改后代码如下:
// background.js function Action(tab) { // 提前保存构造函数的实例指向 const _this = this; // 套一层Promise等待异步逻辑执行完成 return new Promise((resolve) => { function domTitle() { return document.title; } chrome.scripting.executeScript({target: {tabId: tab.id}, func: domTitle}, injectionResults => { for (const frameResult of injectionResults) { _this.title = frameResult.result; console.log(_this); // 第10行 console.log(_this.title); // 第11行 } // 异步操作完成,返回实例 resolve(_this); }); }) } // 回调改为async异步函数 chrome.contextMenus.onClicked.addListener(async (info, tab) => { // 等待Action的异步逻辑执行完成再获取实例 const action = await new Action(tab); console.log(action); // 第29行 console.log(action.title); // 第30行 });
核心修改点
- 给
Action内部封装了一层Promise,只有等executeScript的回调执行完成后才返回实例,保证外部拿到实例时title属性已经赋值完成 - 提前用
_this变量保存了Action构造函数的实例指向,确保回调内的赋值操作是作用在你创建的实例上 - 事件监听回调改为
async异步函数,用await等待Action的异步逻辑执行完成后,再打印实例和title属性
内容的提问来源于stack exchange,提问作者Francisco Luz
相关产品推荐
相关产品推荐

