admin管理员组文章数量:1416651
For a while I've been using chrome.runtime.sendMessage(message, callback)
for messages from my content script that need to run a callback function after receiving a response from the background.
I've also got a long-lived connection that is used for sending messages from the background to the content script (without it being a response to a message initiated by the content script):
backgroundPort = chrome.runtime.connect({ name: "contentScript" });
backgroundPort.onMessage.addListener(function(message){
if (message["action"] == "something"){
// Do stuff
}
});
As far as I can tell, backgroundPort.postMessage()
does not support callback messages which means messages that have a callback need to use chrome.runtime.sendMessage()
.
The problem with this approach is that there is a lot of overhead in setting up a new connection between content script/background for each message, so I'm trying to get callback functionality into the existing long-lived connection through backgroundPort
, but it gets kind of messy.
Anyone who's been able to e up with an elegant solution?
For a while I've been using chrome.runtime.sendMessage(message, callback)
for messages from my content script that need to run a callback function after receiving a response from the background.
I've also got a long-lived connection that is used for sending messages from the background to the content script (without it being a response to a message initiated by the content script):
backgroundPort = chrome.runtime.connect({ name: "contentScript" });
backgroundPort.onMessage.addListener(function(message){
if (message["action"] == "something"){
// Do stuff
}
});
As far as I can tell, backgroundPort.postMessage()
does not support callback messages which means messages that have a callback need to use chrome.runtime.sendMessage()
.
The problem with this approach is that there is a lot of overhead in setting up a new connection between content script/background for each message, so I'm trying to get callback functionality into the existing long-lived connection through backgroundPort
, but it gets kind of messy.
Anyone who's been able to e up with an elegant solution?
Share Improve this question edited Dec 10, 2014 at 6:52 Woodgnome asked Dec 9, 2014 at 15:54 WoodgnomeWoodgnome 2,4015 gold badges29 silver badges54 bronze badges 2-
So your problem is to have a
postMessage(message, callback)
function? This can be arranged, in principle. – Xan Commented Dec 9, 2014 at 16:19 -
For a long-lived connection, yes. I could send messages back from the background with
message["action"] = "doStuffCallback"
, but I don't think it's a good solution. – Woodgnome Commented Dec 9, 2014 at 16:30
2 Answers
Reset to default 5If you look at your background script as socket server (Port object is basically simulating sockets), you could use something called "acknowledgments" that is used in Nodejs, socket.io library.
Basically you store your callbacks functions inside object by giving them unique identifier that you pass to the other side.
// 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
});
Other side passes result with that unique identifier returned, by which you an identify what to do.
// 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
});
}
});
});
chrome.runtime.sendMessage works using "Port" object at lower level so the actual implementation of sendMessage callback should be similar to this in principle.
To put the callback part in a function and return a response value, we can use Promise(code adapted from @antanas_sepikas'):
function myPostMessage(message){
var address = Math.random().toString(36);
message.acknowledgment =address;
acknowledgments[address] = function (data) {
// callback function
// do what you like with result data
return some_data;
};
port.postMessage(message)
let initPromise = new Promise((resolve, reject) => {
port.onMessage.addListener(function (response) {
var callback = acknowledgments[response.acknowledgment];
if (callback) {
delete acknowledgments[response.acknowledgment];
resolve(callback(response.data));
// don't forget to unset acknowledgment, because it's
// supposed to exists only until it's been called.
}
// other message types handling });
})
return initPromise;
}
var res = await myPostMessage(msg);
And you can also add a timeout if needed.
本文标签: javascriptChrome extension longlived message connectionhow to use callback functionsStack Overflow
版权声明:本文标题:javascript - Chrome extension long-lived message connection - how to use callback functions? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745252991a2649933.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论