chrome extension - sendResponse not waiting for async function

浪尽此生 提交于 2019-12-31 03:01:12

问题


I am having an issue of asynchronicity (I believe). sendResponse() in contentscript.js does not wait for getThumbnails() to return.

I am sending a message in 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)   
      }
);

Then, in contentscript.js I listen for this message:

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

But it is also possible that the problem is coming from my getThumnails() function, because most of the times, payload is null and not undefined. So getThumbnails() might return before it is completely executed. If this is the case, I have no idea why...

I also tried this code for 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;
};

But this does not work, it seems to break my code...


回答1:


The callback of onMessage should return true in order to keep the internal messaging channel open so that sendResponse can work asynchronously.

The problem is, your callback is declared with async keyword which means it returns a Promise so it can't return a literal true value because Chrome extensions API doesn't support Promise and hence can't resolve it.

Use a standard function callback and a nested async 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
  }
});


来源:https://stackoverflow.com/questions/53024819/chrome-extension-sendresponse-not-waiting-for-async-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!