再说一次:错误:尝试使用断开连接的端口对象,如何?

时间:2014-04-08 17:20:05

标签: javascript google-chrome tabs google-chrome-app content-script

这是我的设置

background.js

var port = null;
function setPort() {
    chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
        port = chrome.tabs.connect(tabs[0].id, {name: "CONTENTSCRIPT"});
    });
}

// when i click on something, get the port and send a message
function clickHandler(e) {
    setPort();
    if (port) {
        port.postMessage({key: 'message', value: true});
    }
}

contentscript.js

chrome.runtime.onConnect.addListener(function (port) {
    if (port.name == "CONTENTSCRIPT") {
        port.onMessage.addListener(function (msg) {
            console.log(msg);
        });
    }
});

我正在做的是点击随机标签上的contextMenu按钮并尝试发送一个meessage。

发生的事情是,我点击的第一个时间,没有任何反应,没有错误。我第二次点击消息就会通过。

如果我切换到另一个标签,然后点击菜单按钮,我会收到Error: Attempting to use a disconnected port object错误。如果我再次点击该消息将成功发送

我尝试使用var port = chrome.runtime.connect({name: "CONTENTSCRIPT"});,但每次都出现错误的端口

想法?

1 个答案:

答案 0 :(得分:4)

您的问题在于chrome.tabs.query是异步的。

执行setPort(),它会在query执行回调之前立即返回并设置端口。目前,port为空或指向您之前标签的端口。

因此,您要么没有错误,要么出错,因为旧端口无效。

发生这种情况后,query中的回调即被执行,并且port已设置为下次通信。


因此,要解决此问题,您需要在调用链中设置端口后发送消息。例如:

function setPort(callback) {
    chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
        port = chrome.tabs.connect(tabs[0].id, {name: "CONTENTSCRIPT"});
        callback(port);
    });
}

function clickHandler(e) {
    setPort( function (port) {
        if (port) { port.postMessage({key: 'message', value: true}); }
    });  
}

编辑:顺便说一下,你应该重用一个端口,这就是重点。如果您每次重新建立连接,最好使用sendMessage,但我认为您只使用上面的代码进行测试。