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

标签 javascript google-chrome-extension

<分区>

我遇到了异步问题(我相信)。 contentscript.js 中的 sendResponse() 不会等待 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)   
      }
);

然后,在 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;
};

但问题也可能来 self 的 getThumnails() 函数,因为大多数时候,payload 为 null 而不是未定义。所以 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;
};

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

最佳答案

onMessage 的回调应该返回一个literal true 值 ( documentation ) 以保持内部消息 channel 打开,以便 sendResponse 可以异步工作。

问题

您的回调是使用 async 关键字声明的,因此它返回一个 Promise,而不是文字 true 值。 Chrome 扩展 API 不支持在 onMessage 回调的返回值中使用 Promise 直到 https://crbug.com/1185241是固定的,所以它只是被忽略,端口立即关闭,调用者收到 undefined 作为响应。

解决方案

去掉(request, sender, sendResponse)之前的async关键字,然后...

解决方案 1 调用可以作为 IIFE 嵌入的 async 函数:

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
  }
});

解决方案 2 声明一个单独的 async 函数并从 onMessage 监听器调用它:

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.message === "get_thumbnails") {
    processMessage(msg).then(sendResponse);
    return true; // keep the messaging channel open for sendResponse
  }
});

async function processMessage(msg) {
  console.log('Processing message', msg);
  // .................
  return 'foo';
}

关于javascript - chrome 扩展 - sendResponse 不等待异步功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53024819/

相关文章:

javascript - 内容脚本没有收到消息

javascript - 在客户端 javascript 中使用/生产经过训练的机器学习模型?

javascript - 从单独的 iframe 重新加载 iframe

javascript - Angular 6 - 更改变量但不刷新 View

url - 在 Google Chrome 中检测空的新标签打开

css - 使元素不受CSS规则影响

c# - 是否需要引用变量才能将它们包含在闭包中?

javascript - 为什么 Meteor Collection 没有反应性行为?

javascript - Emberjs 应用程序在除 Index 之外的所有路由上加载

javascript - 重新声明 JavaScript 函数