I have the following method that is called from the background script of my Chrome Extension. The goal is to send a message to a specific tab and then call provided callback method with the result. The important part is that the callbackDone
must be always called at some point in time. So it goes as such:
function sendToTab(nTabID, callbackDone)
{
(function()
{
chrome.tabs.sendMessage(nTabID, {
action: "update01"
},
function(response)
{
if(chrome.runtime.lastError)
{
//Failed to send message to the page
if(callbackDone)
callbackDone(nTabID, null); //Page never received the message
}
else
{
//Sent message OK
if(response.result === true)
{
if(callbackDone)
callbackDone(nTabID, true); //Success!
}
else
{
if(callbackDone)
callbackDone(nTabID, false); //Page returns failure
}
}
});
}());
}
Then from within the page that processes the message (can be an injected content script
) I handle it as such:
chrome.runtime.onMessage.addListener(onMessageProc);
function onMessageProc(request, sender, sendResponse)
{
if(request.action == "update01")
{
//Do processing .... that sets `bResult`
sendResponse({result: bResult});
}
}
The above approach works quite well, except... Say, there's a page, like Options page script, that does not process my update01
message and instead, it processes its own message as such:
chrome.runtime.onMessage.addListener(onMessageProc);
function onMessageProc(request, sender, sendResponse)
{
if(request.action == "update02") //Note different action ID
{
//Does some other actions...
}
}
In this case when my first sendToTab
method is called for this tab, my callbackDone
is never called, i.e. chrome.tabs.sendMessage
is invoked and it returns immediately but its callback function is never called.
So what am I missing here?
I have the following method that is called from the background script of my Chrome Extension. The goal is to send a message to a specific tab and then call provided callback method with the result. The important part is that the callbackDone
must be always called at some point in time. So it goes as such:
function sendToTab(nTabID, callbackDone)
{
(function()
{
chrome.tabs.sendMessage(nTabID, {
action: "update01"
},
function(response)
{
if(chrome.runtime.lastError)
{
//Failed to send message to the page
if(callbackDone)
callbackDone(nTabID, null); //Page never received the message
}
else
{
//Sent message OK
if(response.result === true)
{
if(callbackDone)
callbackDone(nTabID, true); //Success!
}
else
{
if(callbackDone)
callbackDone(nTabID, false); //Page returns failure
}
}
});
}());
}
Then from within the page that processes the message (can be an injected content script
) I handle it as such:
chrome.runtime.onMessage.addListener(onMessageProc);
function onMessageProc(request, sender, sendResponse)
{
if(request.action == "update01")
{
//Do processing .... that sets `bResult`
sendResponse({result: bResult});
}
}
The above approach works quite well, except... Say, there's a page, like Options page script, that does not process my update01
message and instead, it processes its own message as such:
chrome.runtime.onMessage.addListener(onMessageProc);
function onMessageProc(request, sender, sendResponse)
{
if(request.action == "update02") //Note different action ID
{
//Does some other actions...
}
}
In this case when my first sendToTab
method is called for this tab, my callbackDone
is never called, i.e. chrome.tabs.sendMessage
is invoked and it returns immediately but its callback function is never called.
So what am I missing here?
Share Improve this question asked Sep 22, 2014 at 0:49 c00000fdc00000fd 22.3k37 gold badges202 silver badges438 bronze badges 3- I don't think that's all relevant code. – Xan Commented Sep 22, 2014 at 6:37
- @Xan: What are you talking about? – c00000fd Commented Sep 22, 2014 at 8:30
- I thought it's important what's in your listeners. It is, but your code snippet is sufficient. – Xan Commented Sep 22, 2014 at 9:10
1 Answer
Reset to default 7You are seeing expected behavior.
The documentation states, regarding the callback function:
If you specify the responseCallback parameter, it should be a function that looks like this:
function(any response) {...};
any response
The JSON response object sent by the handler of the message. If an error occurs while connecting to the specified tab, the callback will be called with no arguments andruntime.lastError
will be set to the error message.
There are 3 possible results of sendMessage
executing.
There was a listener, and it called
sendResponse
.
Then, the callback is called with the response as a parameter.There was a listener, and it terminated without calling
sendResponse
(synchronously or asynchronously).
Then, the callback is not called at all.There was some sort of error sending the message.
Then, the callback is called with no arguments andchrome.runtime.lastError
set.
If you need your callback to execute in any circumstance, you'll need a "default" case in your listeners that calls sendResponse
.