Javascript chrome.runtime.onMessage响应与异步等待

Javascript chrome.runtime.onMessage响应与异步等待,javascript,google-chrome-extension,async-await,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(function(data, MessageSender, sendResponse

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

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

    // returns true if asyncronous is needed
    if (async) return true;
});
但是,当我发送消息时,我没有定义

从chrome.runtime.onMessage.addListener的文档中:

当事件侦听器返回时,此函数无效,除非 您从事件侦听器返回true,以指示您希望发送 异步响应(这将使消息通道对 另一端(直到调用sendResponse)

当我使用回调时,这种方法就可以工作了

chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) =>{
    getKey(key => {
        sendResponse(key);
    });
    return true;
});
然而,我想利用wait语法。但它似乎不起作用,仍然返回未定义的:

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

老实说,Google Chrome扩展似乎不支持
await
关键字。我以前成功地使用过asynchronous
chrome.runtime.onMessage.addListener,每次尝试使用
await
时,我都会在chrome调试工具中看到这个语法错误,在我使用
await
的那一行:

以下是我测试的方式:

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

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

    // returns true if asyncronous is needed
    if (async) return true;
});
我的
测试仪
功能如下所示:

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

    var awaited = await prom;
    return awaited;
}
function asChromeListener(listener) {
  return (message, sender, sendResponse) => {
    const returnValue = listener(message, sender);

    if (isPromise(returnValue)) {
      returnValue.then(sendResponse);
      return true;
    }
    else {
      if (typeof returnValue !== 'undefined') {
        sendResponse(returnValue);
      }
      return false;
    }
  };
}

function isPromise(value) {
  return typeof value === 'object' && value !== null && 'then' in value && 'catch' in value;
}
最后,我的消息发送者是您所期望的:

chrome.runtime.sendMessage({}, function(message) {
    debugger;
    console.log(message);
});

在调试器/控制台中,我总是通过提取到异步函数来解决问题

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  doSomethingWith(request).then(sendResponse);
  return true; // return true to indicate you want to send a response asynchronously
});

async function doSomethingWith(request) {
  var key = await getKey();
  // await .....
  return key;
}
async
函数的返回值隐式包装在
Promise.resolve
中。看


请参阅。

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

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

    var awaited = await prom;
    return awaited;
}
function asChromeListener(listener) {
  return (message, sender, sendResponse) => {
    const returnValue = listener(message, sender);

    if (isPromise(returnValue)) {
      returnValue.then(sendResponse);
      return true;
    }
    else {
      if (typeof returnValue !== 'undefined') {
        sendResponse(returnValue);
      }
      return false;
    }
  };
}

function isPromise(value) {
  return typeof value === 'object' && value !== null && 'then' in value && 'catch' in value;
}
然后您可以使用它,如:

chrome.runtime.onMessage.addListener(asChromeListener(async (message, sender) => {
  return await doMyAsyncWork(message);
});
由于我们使用的是TypeScript,下面是我们实际使用的代码片段(用于泛型类型)

导出函数asChromeListener(侦听器:(消息:M,发送者:S)=>any){
返回(消息:M,发送者:S,发送者响应:R)=>{
const returnValue=侦听器(消息、发送者);
如果(isPromise(returnValue)){
returnValue.then(sendResponse);
返回true;
}
否则{
if(返回值的类型!==‘未定义’){
sendResponse(返回值);
}
返回false;
}
};
}
函数isPromise(值:任意){
返回typeof value==='object'&&value!==null&&then'in value&&catch'in value;
}
您可以试试这个

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

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


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

您没有对async/await的本机支持-您需要使用某种类型的tranapiller来实现该功能。拯救了我的生命,谢谢!!