使用`await`来计算响应会导致发送`undefined`。

huangapple go评论69阅读模式
英文:

Computing response using await results in sending `undefined`

问题

以下是您要翻译的内容:

考虑内容脚本:

(async () => {

    function pause(delay) {
        return new Promise((resolve) => setTimeout(resolve, delay));
    }

    async function myHandler() {
        await pause(1000);
        return ['something 1', 'something 2'];
    }

    function waitForMessage() {
        return new Promise((resolve) => {
            async function onMessageListener(message, sender, sendResponse) {
                chrome.runtime.onMessage.removeListener(onMessageListener);
                resolve(true);
                
                // 以下的响应正常接收!
                // sendResponse({'results': ['something 1', 'something 2']});

                const lines = await myHandler();
                const response = {'results': lines};

                console.log('Responding', response); // 一切正常,{'results': <字符串数组>}
                sendResponse(response);              // 但是,弹出脚本收到了 `undefined`!
            }
            chrome.runtime.onMessage.addListener(onMessageListener);
        });
    }

    waitForMessage();
})();

以下是弹出脚本发送请求的部分:

async function requestFromContentScript() {
    const message = { type: 'request' };
    const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
    const tabId = tabs[0].id;

    return new Promise((resolve) => {
        chrome.tabs.sendMessage(tabId, message, (result) => {
            console.log('Got in callback:', result);
            resolve(result);
        });
    });
}

正如注释所指出的,如果我硬编码响应,弹出脚本能够正常接收。但是,如果使用异步调用计算响应,弹出脚本会收到 undefined。这是如何发生的?

英文:

Consider the content script:

(async () =&gt; {

    function pause(delay) {
        return new Promise((resolve) =&gt; setTimeout(resolve, delay));
    }

    async function myHandler() {
        await pause(1000);
        return [&#39;something 1&#39;, &#39;something 2&#39;];
    }

    function waitForMessage() {
        return new Promise((resolve) =&gt; {
            async function onMessageListener(message, sender, sendResponse) {
                chrome.runtime.onMessage.removeListener(onMessageListener);
                resolve(true);
                
                // The following response is received just fine!
                // sendResponse({&#39;results&#39;: [&#39;something 1&#39;, &#39;something 2&#39;]});

                const lines = await myHandler();
                const response = {&#39;results&#39;: lines};

                console.log(&#39;Responding&#39;, response); // All is fine, {&#39;results&#39;: &lt;array of strings&gt;}
                sendResponse(response);              // However, the popup script receives `undefined`!
            }
            chrome.runtime.onMessage.addListener(onMessageListener);
        });
    }

    waitForMessage();
})();

Here is the part of the popup script sending the request:

async function requestFromContentScript() {
    const message = { type: &#39;request&#39; };
    const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
    const tabId = tabs[0].id;

    return new Promise((resolve) =&gt; {
        chrome.tabs.sendMessage(tabId, message, (result) =&gt; {
            console.log(&#39;Got in callback:&#39;, result);
            resolve(result);
        });
    });
}

As the comments indicate, if I hardcode the response, it is received by the popup script just fine. However, if the response is computed using an asynchronous call, the popup script receives undefined. How can this happen?

答案1

得分: 1

我不做扩展,但快速查看文档 ->
(message: any, sender: MessageSender, sendResponse: function) =&gt; boolean | undefined

所以我有一种感觉,如果你处理这条消息,应该返回true。当前你返回一个Promise

所以根据我有限的扩展知识,我认为这可能有效。

function onMessageListener(message, sender, sendResponse) {
  myHandler().then(async () => {  //或者是一个异步IIFE
     const lines = await myHandler();
     const response = {'results': lines};
     sendResponse(response);
  });
  return true; 
}

chrome.runtime.onMessage.addListener(onMessageListener);
英文:

I don't do extensions, but a quick look at the docs ->
(message: any, sender: MessageSender, sendResponse: function) =&gt; boolean | undefined

So I've a feeling your meant to return true if you handle this message. Currently your returning a Promise.

So with my limited knowledge of extensions, I would think this might work.

function onMessageListener(message, sender, sendResponse) {
  myHandler().then(async () =&gt; {  //or an async IIFE
     const lines = await myHandler();
     const response = {&#39;results&#39;: lines};
     sendResponse(response);
  });
  return true; 
}

chrome.runtime.onMessage.addListener(onMessageListener);

huangapple
  • 本文由 发表于 2023年7月31日 20:59:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76803882.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定