使用异步等待的chrome.runtime.onMessage响应

时间:2017-05-18 19:25:11

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

我想在onMessage侦听器中使用async await:

chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) =>{
    var key = await getKey();
    sendResponse(key);
});

然而,当我发送消息时,我得到了未定义。

来自chrome.runtime.onMessage.addListener的文档:

  

除非事件侦听器返回,否则此函数将变为无效   从事件监听器返回true表示您希望发送一个   异步响应(这将使消息通道保持打开状态   另一端直到调用sendResponse)。

当我使用回调时,这是有效的。

chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) =>{
    getKey(key => {
        sendResponse(key);
    });
    return true;
});

但是我想利用await语法。但它似乎不起作用,仍然返回undefined:

chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) =>{
    var key = await getKey();
    sendResponse(key);
    return true;
});

4 个答案:

答案 0 :(得分:6)

我通过提取到异步函数来解决这个问题。

╔════╦══════╦═══╦═══════╦═══════════╦═══════════╦═══════════╗
║    ║  A   ║ B ║   C   ║     D     ║     E     ║     F     ║
╠════╬══════╬═══╬═══════╬═══════════╬═══════════╬═══════════╣
║  1 ║ Data ║   ║ Count ║ Element 1 ║ Element 2 ║ Element 3 ║
║----║------║---║-------║-----------║-----------║-----------║
║  2 ║ 1    ║   ║   2   ║     1     ║     2     ║     3     ║
║  3 ║ 2    ║   ║   0   ║     5     ║     6     ║           ║
║  4 ║ 3    ║   ║   1   ║     3     ║     4     ║           ║
║  5 ║ 7    ║   ║       ║           ║           ║           ║
║  6 ║ 8    ║   ║       ║           ║           ║           ║
║  7 ║ 9    ║   ║       ║           ║           ║           ║
║  8 ║ 1    ║   ║       ║           ║           ║           ║
║  9 ║ 2    ║   ║       ║           ║           ║           ║
║ 10 ║ 3    ║   ║       ║           ║           ║           ║
║ 11 ║ 7    ║   ║       ║           ║           ║           ║
║ 12 ║ 8    ║   ║       ║           ║           ║           ║
║ 13 ║ 9    ║   ║       ║           ║           ║           ║
║ 14 ║ 3    ║   ║       ║           ║           ║           ║
║ 15 ║ 4    ║   ║       ║           ║           ║           ║
║ 16 ║ 5    ║   ║       ║           ║           ║           ║
╚════╩══════╩═══╩═══════╩═══════════╩═══════════╩═══════════╝

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { doSomethingWith(request).then(sendResponse); return true; // return true to indicate you wish to send a response asynchronously }); async function doSomethingWith(request) { var key = await getKey(); // await ..... return key; } 函数的返回值隐含在async中。请参阅onMessage

请参阅{{3}}。

答案 1 :(得分:1)

老实说,Google Chrome扩展程序看起来不支持await关键字。我以前成功使用过异步chrome.runtime.onMessage.addListener,每次尝试使用await时,我在Chrome调试工具中看到此语法错误,就在我使用的行{ {1}}:

await not supported

以下是我的测试方式:

我创建了一个非常基本的监听器:

await

我的chrome.runtime.onMessage.addListener(function(data, MessageSender, sendResponse) { sendResponse(awaitTester); var async = true; // returns true if asyncronous is needed if (async) return true; }); 函数如下所示:

awaitTester

最后,我的邮件发件人是您所期望的:

function awaitTester() {
    var prom = new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve('test');
        }, 4000);
    });

    var awaited = await prom;
    return awaited;
}

在调试器/控制台中,我始终获取chrome.runtime.sendMessage({}, function(message) { debugger; console.log(message); });

答案 2 :(得分:1)

不确定Chrome扩展程序运行时环境是否支持async / await语法,但是您可以使用转译器(例如Babel)将其转换为例如ES5。然后,您可以定义一个包装函数,如下所示:

| Variable_name                      | Value                    |
+------------------------+--------------------------------------+
| basedir                            | /usr                     |
| innodb_temp_data_file_path         |  ibtmp1:12M:autoextend   |
| datadir                            | /mysql_data              |
| innodb_tmpdir                      |                          |
| max_tmp_tables                     |  32                      |
| slave_load_tmpdir                  |  /mysql_data/mysql_tmp   |
| tmp_disk_table_size                |  4294967295              |
| tmp_memory_table_size              |  33554432                |
| tmp_table_size                     |  33554432                |
| tmpdir                             |  /mysql_data/mysql_tmp   |
+----------------------------+----------------------------------+

然后您可以像这样使用

function asChromeListener(listener) {
  return (message, sender, sendResponse) => {
    const returnValue = listener(message, sender);

    if (isPromise(returnValue)) {
      returnValue.then(sendResponse);
      return true;
    }
    else {
      return false;
    }
  };
}

function isPromise(value) {
  return typeof value === 'object' && value !== null && 'then' in value && 'catch' in value;
}

由于我们使用 TypeScript ,所以这也是我们实际使用的代码段(具有通用类型)。

chrome.runtime.onMessage.addListener(asChromeListener(async (message, sender) => {
  return await doMyAsyncWork(message);
});

答案 3 :(得分:0)

您可以尝试

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  new Promise(async send => {
     

    var key = await getKey();
    send(key);


  }).then(sendResponse)
  return true;
});