chrome扩展-sendResponse不等待异步功能(chrome extension - sendResponse not waiting for async function)

描述:
 
    1. content-script 1 中的 就是给 backgroun 发送了一个 message。(content-script 1 中的内容我就不贴出来了)
 
    2. background 拿到 message 之后 会打开一个 新的标签页, 这个标签页会注入 content-script 2  
 
    3. content-script 2  收到消息后 要在异步中 sendMessage到 background 中。
 
问题:
   最后一步 在setTimeout 中 sendMessage到 background 中时,拿不到message,同时 background 控制台还报如下错误。
   Unchecked runtime.lastError: The message port closed before a response was received.  意思大致是:不受控制的运行时。lastError:在收到响应之前关闭的消息端口。没有拿到 response 想要 ,就关闭了这次通信。

 

 

 
background.js 监听 其它 content-script 1 发来的消息
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse){
    console.log('这里是后台', request,'|||||||||||||', sender, '||||||||||||', sendResponse);
    if(request.message === 'autoReply'){
        console.log('后台已经收到',request.data);
        sendResponse('我后台已收到');
        // 打开一个新窗口
        chrome.tabs.create({url: 'https://xxx.com/'}, tab => {
            console.log('新打开的 tab 信息', tab);
            if(!tab.id){
                sendResponse({
                    state: 'rejected',
                    message: '打开新窗口失败'
                })
                return;
            }
            console.log('新tab id', tab.id);
            // 轮询 打开的新窗口 status 状态
            let timer = setInterval(()=>{
                chrome.tabs.get(tab.id, (tab)=>{
                    if(tab.status === 'complete'){
                        // 取消轮询
                        timer && clearTimeout(timer);
                        console.log('页面加载完成了, 一秒后开始发送消息 到 content-script 2');
                        // 延迟1s 后给 新打开的 标签页 发送 message
                        setTimeout(()=>{
                            chrome.tabs.sendMessage(tab.id, {
                                message: request.message,
                                data: request.data
                            }, function(response){
                                // 一会主要看这里的打印情况
                                console.log('dongdong.js 的回复', response);
                            });
                        }, 1000)
                    }
                });
            }, 1000);

        });
    }
});

 

content-script 2:
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse){
    console.log('content-script 2 收到消息', request);
    if(request.message === 'autoReply'){
        console.log('cs-dd.js 3秒后执行了自动回复')
/*         
        // 正常在这里写 sendResponse 是没有 会提的 background.js 会正常打印 response
        sendResponse({
            message: "content-script 2 已经收到"
        });
 */
        setTimeout(()=>{
            // 在这个异步 中进行 sendResponse 时候 background.js 打印的 response 为 undefined
            sendResponse({
                message: "content-script 2 执行了自动回复"
            });

            // do something ....
            // autoReply( request.data );
        }, 3000)
    }
    // onMessage 返回 true 时候 sendResponse 就可以写在异步当中了
    // return true;
});

 

解决方法:
onMessage的回调应返回 true ,以保持内部消息通道开放,以便sendResponse可以异步工作。
 
调整后的 content-script 2
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse){
    console.log('content-script 2 收到消息', request);
    if(request.message === 'autoReply'){
        console.log('cs-dd.js 3秒后执行了自动回复')
/*         
        // 正常在这里写 sendResponse 是没有 会提的 background.js 会正常打印 response
        sendResponse({
            message: "content-script 2 已经收到"
        });
 */
        setTimeout(()=>{
            // 在这个异步 中进行 sendResponse 时候 background.js 打印的 response 为 undefined
            sendResponse({
                message: "content-script 2 执行了自动回复"
            });

            // do something ....
            // autoReply( request.data );
        }, 3000)
    }
    // onMessage 返回 true 时候 sendResponse 就可以写在异步当中了
    return true;
});

 

当 return true; 时,在异步中 sendResponse 就可以成功到达 background 中。

 


参考:https://www.it1352.com/2107077.html

 

 

posted @ 2021-01-23 11:26  暗恋桃埖源  阅读(2147)  评论(0编辑  收藏  举报