chrome.tabs.sendMessage回调函数未被调用。为什么?

问题描述:

我从我的Chrome扩展的背景脚本中调用以下方法。目标是将消息发送到特定的选项卡,然后调用提供的回调方法和结果。重要的部分是callbackDone必须是总是在某个时间点调用。如此这般这样:chrome.tabs.sendMessage回调函数未被调用。为什么?

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 
       } 
      } 
     }); 
    }()); 
} 

然后从处理消息的页面中(可以是注入content script),我把它处理这样的:

chrome.runtime.onMessage.addListener(onMessageProc); 

function onMessageProc(request, sender, sendResponse) 
{ 
    if(request.action == "update01") 
    { 
     //Do processing .... that sets `bResult` 

     sendResponse({result: bResult}); 
    } 
} 

上述方法工作的很好,除了......我说,有一个页面,像选项页面脚本,不处理我update01消息,相反,它处理自己的消息,例如:

chrome.runtime.onMessage.addListener(onMessageProc); 

function onMessageProc(request, sender, sendResponse) 
{ 
    if(request.action == "update02") //Note different action ID 
    { 
     //Does some other actions... 
    } 
} 

在这种情况下,当我为此选项卡调用第一个sendToTab方法时,我的callbackDone永远不会被调用,即调用chrome.tabs.sendMessage并立即返回,但其回调函数永远不会被调用。

那么我在这里错过了什么?

+0

我不认为这是所有相关的代码。 – Xan 2014-09-22 06:37:11

+0

@Xan:你在说什么? – c00000fd 2014-09-22 08:30:37

+0

我认为这很重要你的听众。它是,但是你的代码片段就足够了。 – Xan 2014-09-22 09:10:47

您正在看到预期的行为。

documentation状态,对于回调函数:

如果指定responseCallback参数,它应该是一个函数,看起来像这样:

function(any response) {...};

any response
的JSON由消息的处理程序发送的响应对象。如果在连接到指定选项卡时发生错误,则将调用不带任何参数的回调,并且runtime.lastError将设置为错误消息。

执行sendMessage有3种可能的结果。

  1. 有一个听众,它叫sendResponse
    然后,将回应作为参数调用。

  2. 有一个监听程序,它终止时没有调用sendResponse(同步或异步)。
    然后,回调根本不叫

  3. 发送消息时出现某种错误。
    然后,回调被调用,没有参数和chrome.runtime.lastError集合。

如果你需要回调在任何情况下执行,你需要在你的听众调用sendResponse“默认”的情况。

+0

谢谢。尽管如果你的3分被包含在文档中,它确实会有所帮助。或者至少它会消除错误和混乱......你怎么知道这一切? – c00000fd 2014-09-22 09:21:35

+0

在这种情况下,我只是测试它。然后,与文档交叉引用,上面的引用可以像这样解释。 – Xan 2014-09-22 10:07:58

+0

@ c00000fd你没有调用你的'sendResponse',并想知道为什么'response'函数永远不会被调用?看起来像我预期的行为。 – Teepeemm 2014-09-22 14:27:17