chrome 扩展 - sendResponse 不等待异步功能

Jer*_*lam 9 javascript google-chrome-extension

我有一个异步问题(我相信)。sendResponse()在contentscript.js中不等待getThumbnails()返回。

我在popup.js 中发送消息:

chrome.tabs.sendMessage(tabs[0].id, {message: "get_thumbnails", tabUrl: tabs[0].url},
      function (respThumbnails) {
            const thumbUrl = respThumbnails.payload;
            console.log("payload", thumbUrl)   
      }
);
Run Code Online (Sandbox Code Playgroud)

然后,在contentscript.js我听这条消息:

chrome.runtime.onMessage.addListener(async function(request,sender,sendResponse) {
    if(request.message === "get_thumbnails") {
        const payload = await getThumbnails();
        console.log("thumbPayload after function:", payload)
        sendResponse({payload:payload});   
    }
});


async function getThumbnails() {
    let tUrl = null;
    var potentialLocations = [
        {sel: "meta[property='og:image:secure_url']",   attr: "content" },
        {sel: "meta[property='og:image']",              attr: "content" },
    ];

    for(s of potentialLocations) {
        if(tUrl) return
        const el = document.querySelector(s.sel);
        if(el) {
            tUrl = el.getAttribute(s.attr) || null;
        } 
    }
    return tUrl;
};
Run Code Online (Sandbox Code Playgroud)

但也有可能问题出在我的getThumnails()函数上,因为在大多数情况下,payload 为 null而不是 undefined。所以getThumbnails()可能会在它完全执行之前返回。如果是这样的话,我不知道为什么......

我也试过这个代码getThubnails():

async function getThumbnails() {
  let x = await function() {
    let tUrl = null;
    var potentialLocations = [
        {sel: "meta[property='og:image:secure_url']",   attr: "content" },
        {sel: "meta[property='og:image']",              attr: "content" },
    ];

    for(s of potentialLocations) {
        if(tUrl) return
        const el = document.querySelector(s.sel);
        if(el) {
            tUrl = el.getAttribute(s.attr) || null;
        } 
    }
    return tUrl;
  }
  return x;
};
Run Code Online (Sandbox Code Playgroud)

但这不起作用,它似乎破坏了我的代码......

wOx*_*xOm 25

onMessage 的回调应该返回一个文字 true值(文档),以保持内部消息通道打开,以便 sendResponse 可以异步工作。

问题是,您的回调是用async关键字声明的,这意味着它返回 aPromise因此它不能返回文字true值。Chrome 扩展 API 不支持回调的返回值中的 Promise,因此它被忽略。

使用标准函数回调和嵌套的异步 IIFE:

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.message === "get_thumbnails") {
    (async () => {
      const payload = await getThumbnails();
      console.log("thumbPayload after function:", payload)
      sendResponse({payload});
    })();
    return true; // keep the messaging channel open for sendResponse
  }
});
Run Code Online (Sandbox Code Playgroud)

  • 这对我来说不起作用,直到我删除了顶级“addListener”函数中的“async”关键字。`chrome.runtime.onMessage.addListener(异步函数(` >>> `chrome.runtime.onMessage.addListener(函数(` (3认同)
  • @Vadorequest,您所做的正是这个答案所显示的。我添加了一个明确的注释来澄清它。 (3认同)
  • 你刚刚救了我!对于未来的读者,请删除异步!!!使用 thens、sendReponse 和 return true,它将解决您所有的问题! (3认同)