最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to avoid "The message port closed before a response was received" error when using await in t

programmeradmin0浏览0评论

I am writing a chrome extension with node module "chrome-extension-async" and meeting a problem when use await in the listener of background.

The content.js which will be injected into the page will send a message to the background, asking it to do some IO operations which is async:

// content.js
const package = await chrome.runtime.sendMessage({param: ...})
console.log(package)

// background.js
chrome.runtime.onMessage.addListener(async (request, sender, 
sendResponse) => {
    const value  = await doIOOperation();
    sendResponse(value);
})

However, chrome will report errors like below:

Uncaught (in promise) Error: The message port closed before a response was received.

I think there must be some conflict when using async/await in the listener, Anyone know how to solve this problem?

I am writing a chrome extension with node module "chrome-extension-async" and meeting a problem when use await in the listener of background.

The content.js which will be injected into the page will send a message to the background, asking it to do some IO operations which is async:

// content.js
const package = await chrome.runtime.sendMessage({param: ...})
console.log(package)

// background.js
chrome.runtime.onMessage.addListener(async (request, sender, 
sendResponse) => {
    const value  = await doIOOperation();
    sendResponse(value);
})

However, chrome will report errors like below:

Uncaught (in promise) Error: The message port closed before a response was received.

I think there must be some conflict when using async/await in the listener, Anyone know how to solve this problem?

Share Improve this question edited Mar 18, 2022 at 2:23 pppery 3,81425 gold badges37 silver badges50 bronze badges asked Jan 3, 2019 at 6:12 Kyle HuKyle Hu 1111 gold badge1 silver badge5 bronze badges 5
  • 6 I think you need to add return true just like with the classic callback version, but the listener can't be async - you'll have to put the async code into IIFE or another function. I also think the WebExtension polyfill is better and BTW it correctly handles this case. – woxxom Commented Jan 3, 2019 at 7:04
  • @wOxxOm sendResponse is planned to be phased out from the W3C draft. And it is to be replaced by returning a Promise. I'm assuming this is now happening on Chrome, with some users reporting that this issue is happening on Chrome 71. developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/… – tom_mai78101 Commented Jan 11, 2019 at 14:20
  • 1 @tom_mai78101, nope, W3C is not related to Chrome API, which is not Promise-based. The OP simply uses a promisifier library, which apparently confused you. – woxxom Commented Jan 11, 2019 at 14:40
  • @wOxxOm Ahh, sorry my mistake. Thanks for the clarification. – tom_mai78101 Commented Jan 11, 2019 at 15:08
  • As per @wOxxOm's comment - see stackoverflow.com/a/20077854/868159 – oatsoda Commented Feb 26, 2020 at 8:33
Add a comment  | 

2 Answers 2

Reset to default 11
const asyncFunctionWithAwait = async (request, sender, sendResponse) => {...}

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    asyncFunctionWithAwait(request, sender, sendResponse)

    return true
})

worked for me

To expand on all the notes and clarify @RomanistHere's answer:

// a couple example async example functions
var greet;
const whatever = async function(){
    greet = "hello";
}
const getSomething = async function(){
    return "bob";
}

// set up a function outside the callback, 
// ... giving freedom to leverage async/await.
const asyncFunctionWithAwait = async (request, sender, sendResponse) => {
    
    // now we can do await's normally here
    await whatever();
    let name = await getSomething();
    
    // since our response function is carried through "by reference",
    // therefore we can call it as if it were within the listener callback.
    sendResponse(greet + name)

}

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {

    // exec in the body of this callback,
    // ... passing original function through.
    asyncFunctionWithAwait(request, sender, sendResponse)

    // per:
    // http://developer.chrome.com/extensions/runtime.html#event-onMessage
    //
    // This function becomes invalid when the event listener returns, 
    // unless you return true from the event listener to indicate you 
    // wish to send a response asynchronously (this will keep the message 
    // channel open to the other end until sendResponse (3rd arg) is called).
    return true;

});

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论