我正在尝试使用 JavaScript 为我的 chrome 扩展程序循环此页面。它的作用是保持运行,直到收到“chrome.tabs.sendMessage”的响应以停止运行。 “chrome.tabs.sendMessage”的响应函数发送正确的 bool 值,但下面的其余代码不起作用。当我运行此代码时,console.log(cont) 首先打印,但 console.log(response[0]) 应该首先运行。我认为这是异步编程的问题,但我对 javascript 和这种编程很陌生,所以我不知道如何解决它。如有任何建议或帮助,我们将不胜感激,谢谢!
var temp = false;
function injectTheScript() {
var name = document.getElementById('name').value;
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(tabs[0].id, {file: "utilities.js"}, function(){
chrome.tabs.sendMessage(tabs[0].id, name, function(response){
temp = response[0];
console.log(response[0]);
});
});
});
return temp;
}
function nextName() {
var cont = true;
while(cont){
cont = injectTheScript();
console.log(cont); //this gets printed first but should be printed second
}
}
document.getElementById('start').addEventListener('click', nextName);
这个页面是 popup.js 顺便说一下,它是 popup.html 背后的脚本,当你点击图标时 Chrome 扩展程序会显示该脚本。
最佳答案
每个 JavaScript 脚本的上下文都是单线程的,因此您的同步 while
循环将在一个事件循环任务中永远运行,这意味着 query()、executeScript() 和 sendMessage 的异步回调都不会发生() 将永远运行,并且您的扩展将无休止地消耗 100% CPU。
解决方案是使循环异步,并让injectTheScript通过Promise
返回内容脚本的响应值:
function injectTheScript() {
return new Promise(resolve => {
const name = document.getElementById('name').value;
chrome.tabs.query({active: true, currentWindow: true}, ([tab]) => {
chrome.tabs.executeScript(tab.id, {file: 'utilities.js'}, () => {
chrome.tabs.sendMessage(tab.id, name, resolve);
});
});
});
}
async function nextName() {
while (await injectTheScript()) {
console.log('yay');
}
}
上面的代码期望内容脚本中的 onMessage 监听器通过 sendResponse 返回一个 bool 值:
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
// do something
// ..............
sendResponse(true); // or false
});
如果需要,请参阅有关 Promise
和异步 JavaScript 的教程以获取更多信息。
关于javascript - 如何循环处理请求的 javascript 页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60801650/