javascript sendResponse未等待async函数或Promise的resolve [重复]

eh57zj3b  于 2023-04-19  发布在  Java
关注(0)|答案(1)|浏览(129)

此问题已在此处有答案

chrome.runtime.onMessage response with async await(8个回答)
1年前关闭。
我有一个异步问题(我相信)。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()函数出了问题,因为大多数时候,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;
};

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

hpxqektj

hpxqektj1#

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

问题

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

解决方案

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

方案一调用一个可作为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
  }
});

方案二单独声明一个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';
}

相关问题