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

时间:2018-10-27 18:03:42

标签: 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;
};

但是问题也可能来自我的getThumnails()函数,因为在大多数情况下,有效载荷为空并且不是不确定的。因此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;
};

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

1 个答案:

答案 0 :(得分:1)

onMessage should return true的回调,以保持内部消息通道开放,以便sendResponse可以异步工作。

问题是,您的回调函数使用async关键字声明,这意味着它返回了Promise,因此它无法返回原义的true值,因为Chrome扩展程序API不支持承诺,因此无法解决,您需要使用标准函数回调。

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