Woo*_*ome 6 javascript google-chrome google-chrome-extension
一段时间以来,我一直在使用chrome.runtime.sendMessage(message, callback)内容脚本中的消息,这些消息需要在收到后台响应后运行回调函数。
我还有一个长期连接,用于从后台向内容脚本发送消息(而不是对内容脚本发起的消息的响应):
backgroundPort = chrome.runtime.connect({ name: "contentScript" });
backgroundPort.onMessage.addListener(function(message){
if (message["action"] == "something"){
// Do stuff
}
});
Run Code Online (Sandbox Code Playgroud)
据我所知,backgroundPort.postMessage()不支持回调消息,这意味着具有回调的消息需要使用chrome.runtime.sendMessage().
这种方法的问题在于,在每条消息的内容脚本/背景之间建立新的连接会产生大量开销,因此我尝试通过将回调功能添加到现有的长期连接中backgroundPort,但它变得很友好的凌乱。
谁能想出一个优雅的解决方案?
如果您将后台脚本视为套接字服务器(端口对象基本上是模拟套接字),您可以使用 Nodejs、socket.io 库中使用的称为“确认”的东西。
基本上,您可以通过为回调函数提供传递给另一端的唯一标识符来将回调函数存储在对象内。
// on the sending side
// this variable will store callbacks
var acknowledgments = {};
var port = chrome.runtime.connect();
// this variable will be unique callback idetifier
var address = Math.random().toString(36);
// You create acknowledgment by identifying callback
acknowledgments[address] = function (data) {
// callback function
// do what you like with result data
};
port.postMessage({
acknowledgment: address,
data: messageData
})
port.onMessage.addListener(function (message) {
var callback = acknowledgments[message.acknowledgment];
if (callback) {
callback(message.data);
// don't forget to unset acknowledgment, because it's
// supposed to exists only until it's been called.
delete acknowledgments[message.acknowledgment];
return;
}
// other message types handling
});
Run Code Online (Sandbox Code Playgroud)
另一方传递带有返回的唯一标识符的结果,您可以通过该标识符确定要做什么。
// on the listening side
chrome.runtime.onConnect.addListener(function (port) {
port.onMessage.addListener(function (message) {
if (message.acknowledgment) {
// do stuff you need to do
// then return result
port.postMessage({
acknowledgment: message.acknowledgment
data: stuffYouHaveDoneResult
});
}
});
});
Run Code Online (Sandbox Code Playgroud)
chrome.runtime.sendMessage 在较低级别使用“Port”对象工作,因此原则上 sendMessage 回调的实际实现应该与此类似。
| 归档时间: |
|
| 查看次数: |
3101 次 |
| 最近记录: |