javascript - async、await、promise 的响应未定义

标签 javascript google-chrome-extension promise async-await

在我的eventPage.js (背景,持久= false):

chrome.runtime.onMessage.addListener(async function(request, sender, sendResponse) {

    await new Promise((resolve, reject) => { 
        chrome.downloads.search({id: files[i]}, function (item) { 
            sendfiles.push(item[0].id);
            resolve();
        });
    });

    console.log(sendfiles); // contains (item[0].id), means it did wait.

    sendResponse("hello"); // Should send hello back

    return true;
});

在我的 popup.js 中:

chrome.runtime.sendMessage("",(response) => {
    alert(response); // alerts undefinded instead of hello
});

我的错误: Unchecked runtime.lastError: The message port closed before a response was received.

正如代码注释中所写,它应该响应来自 popup.js 的请求。与 "hello" ,但是因为它在 Promise 中等待,我收到错误和 response变成undefinded在我可以之前 sendResponse我的"hello" (我猜这就是正在发生的事情)..

最佳答案

This function becomes invalid when the event listener returns, unless you return true from the event listener to indicate you wish to send a response asynchronously (this will keep the message channel open to the other end until sendResponse is called).

来自here

但是使用 async-await,你的函数将返回一个 Promise。

所以你想这样做:

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {

    chrome.downloads.search({id: files[i]}, 
      function (item) { 
        sendResponse(item[0].id);
      }
    );

   return true;
});

但实际上,你想这样做:

chrome.runtime.onMessage.addListener(
  (req, sender, sendResponse) => {
    chrome.downloads.search({id: files[i]}, 
       item => sendResponse(item[0].id);
    );
   return true;
});

或者至少,我愿意! :-)

用于循环。您想要返回一个文件数组。所以你在程序中所做的是:

  1. 创建一个“文件的 Promise 或未定义”数组
  2. 等待所有这些 Promise 得到解决。
  3. 过滤掉未定义的内容。
  4. 返回文件数组。
chrome.runtime.onMessage.addListener(
  (req, sender, sendResponse) => {
   if (req !== "files") { return } // why wait?

   Promise.all(files.map(file => 
     new Promise(resolve =>     
       chrome.downloads.search({id: file},
         item => resolve(item[0].exists ? 
         {
            filename: [item[0].filename, 
            id: item[0].id]
          } : undefined)))))
    .then(res => res.filter(i => !!i)) //remove empty
    .then(sendResponse)

  return true;
});

基本上,如果您使用循环或变量,那么您就做错了。仅常量和函数。

希望这有帮助。

关于javascript - async、await、promise 的响应未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60353737/

相关文章:

javascript - 预加载外部网站内容,然后重定向

javascript - Chrome 扩展程序内容脚本未触发代码

javascript - 从另一个函数内部调用日期选择器选项函数

javascript - 如何在 React 中等待多个异步等待请求

javascript - 从tensorflow js模型获取原始输出

javascript - 尝试 extjs 5 简单网格面板(示例不起作用)

javascript - Chrome扩展回调函数和并发

javascript - Chrome 扩展 : how to trap/handle content-script errors globally?

javascript - Promise 的脚本执行顺序

java - 如何获取嵌套 JSTL c :forEach from JSP to JS 的索引