Javascript browser.runtime.sendMessage()在异步调用sendResponse()之前履行的承诺
我制作了一个FirefoxWebExtension,它可以与可执行文件交互(使用) 以下是扩展的清单:Javascript browser.runtime.sendMessage()在异步调用sendResponse()之前履行的承诺,javascript,firefox-addon,firefox-addon-webextensions,Javascript,Firefox Addon,Firefox Addon Webextensions,我制作了一个FirefoxWebExtension,它可以与可执行文件交互(使用) 以下是扩展的清单: // manifest.json file { "name": "My Extension", "short_name": "myext", "version": "2.7", "manifest_version": 2, "background": { "scripts": ["background-script.js"], "persistent":
// manifest.json file
{
"name": "My Extension",
"short_name": "myext",
"version": "2.7",
"manifest_version": 2,
"background": {
"scripts": ["background-script.js"],
"persistent": true
},
"externally_connectable": {
"ids": ["*"],
"http://localhost/*"]
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content-script.js"]
}
],
"applications": {
"gecko": {
"id": "myext@myext.mysite.com",
"strict_min_version": "50.0.0"
}
},
"icons": {
"16": "icon-16.png",
"32": "icon-32.png",
"128": "icon-128.png"
},
"permissions": [
"nativeMessaging",
"webRequest"
]
}
这是我的背景脚本:
// background-script.js
var port;
browser.runtime.onMessage.addListener(function(request, sender, sendResponse)
{
port = browser.runtime.connectNative("ping_pong");
var result = port.postMessage(request);
port.onMessage.addListener(function(response)
{
console.log("Received: " + JSON.stringify(response));
sendResponse(response);
});
});
sendResponse(response);
我对背景脚本中的以下行有问题:
// background-script.js
var port;
browser.runtime.onMessage.addListener(function(request, sender, sendResponse)
{
port = browser.runtime.connectNative("ping_pong");
var result = port.postMessage(request);
port.onMessage.addListener(function(response)
{
console.log("Received: " + JSON.stringify(response));
sendResponse(response);
});
});
sendResponse(response);
在后台脚本的sendResponse()
之前调用内容脚本的方法handleResponse()
因此,当可执行文件执行操作所需时间较长时,可执行文件的结果不会发送到内容脚本,而内容脚本会收到未定义的结果
是否有其他方法将可执行文件的结果从后台脚本发送到内容脚本?或者以另一种方式使用回调?的使用在这里造成了一些混乱。调用您的HandlerResponse()
时,承诺已实现,但没有参数,因为您未调用sendResponse()
而退出了后台脚本的运行时.onMessage
侦听器。如果调用了sendResponse()
,则参数将是message1。因此,您需要调整.then()
以区分未接收参数(sendResponse()
未调用)和包含响应消息的参数(sendResponse()
调用)。如果我没记错的话,如果您使用的是chrome.runtime.sendMessage()
,则除非调用sendResponse()
,否则不会调用您的responseCallback
函数
:
如果发送方发送了响应,则响应将作为JSON对象来实现。否则,它将在没有参数的情况下实现。如果在连接到扩展时发生错误,承诺将被拒绝并显示错误消息
要异步调用sendResponse()
,需要返回true代码>从运行时.onMessage
侦听器
您正在从异步回调中调用sendResponse()
。因此,在调用sendResponse()
之前,您将退出runtime.onMessage
侦听器。如果要执行此操作,但仍要调用sendResponse()
,则需要从运行时.onMessage
侦听器返回true
关于sendResponse()
:
此函数返回一个布尔值。如果您希望在事件侦听器返回后调用sendResponse
,它应该从事件侦听器返回true
因此,您的代码可以是:
browser.runtime.onMessage.addListener(function(request, sender, sendResponse)
{
port = browser.runtime.connectNative("ping_pong");
var result = port.postMessage(request);
port.onMessage.addListener(function portOnMessageListener(response)
{
//sendResponse is only valid once. So, if this is how you want to use it, you need
// to remove the listener, or in some other way not call sendResponse twice.
port.onMessage.removeListener(portOnMessageListener);
console.log("Received: " + JSON.stringify(response));
sendResponse(response);
});
return true;
});
sendResponse()
仅有效一次
sendResponse()
函数仅对一条消息有效(即,每发送一条消息,您只能发送一条响应)。如果希望向内容脚本发送多条消息,则需要以不同的方式进行设置
该消息是一个“JSON对象”。他们可能的意思是,它是从JSON转换而来的,JSON在消息传输过程中被用来表示它
在这里使用的是引起一些混乱。调用您的HandlerResponse()
时,承诺已实现,但没有参数,因为您未调用sendResponse()
而退出了后台脚本的运行时.onMessage
侦听器。如果调用了sendResponse()
,则参数将是message1。因此,您需要调整.then()
以区分未接收参数(sendResponse()
未调用)和包含响应消息的参数(sendResponse()
调用)。如果我没记错的话,如果您使用的是chrome.runtime.sendMessage()
,则除非调用sendResponse()
,否则不会调用您的responseCallback
函数
:
如果发送方发送了响应,则响应将作为JSON对象来实现。否则,它将在没有参数的情况下实现。如果在连接到扩展时发生错误,承诺将被拒绝并显示错误消息
要异步调用sendResponse()
,需要返回true代码>从运行时.onMessage
侦听器
您正在从异步回调中调用sendResponse()
。因此,在调用sendResponse()
之前,您将退出runtime.onMessage
侦听器。如果要执行此操作,但仍要调用sendResponse()
,则需要从运行时.onMessage
侦听器返回true
关于sendResponse()
:
此函数返回一个布尔值。如果您希望在事件侦听器返回后调用sendResponse
,它应该从事件侦听器返回true
因此,您的代码可以是:
browser.runtime.onMessage.addListener(function(request, sender, sendResponse)
{
port = browser.runtime.connectNative("ping_pong");
var result = port.postMessage(request);
port.onMessage.addListener(function portOnMessageListener(response)
{
//sendResponse is only valid once. So, if this is how you want to use it, you need
// to remove the listener, or in some other way not call sendResponse twice.
port.onMessage.removeListener(portOnMessageListener);
console.log("Received: " + JSON.stringify(response));
sendResponse(response);
});
return true;
});
sendResponse()
仅有效一次
sendResponse()
函数仅对一条消息有效(即,每发送一条消息,您只能发送一条响应)。如果希望向内容脚本发送多条消息,则需要以不同的方式进行设置
该消息是一个“JSON对象”。他们可能的意思是,它是从JSON转换而来的,JSON在消息传输过程中被用来表示它
非常感谢您的快速和详尽answer@Thordax,我很高兴能帮上忙。如果要从端口
获取多条消息,可以使用多种方法。但是,看起来您并没有期望端口上出现多条消息。如果是我,只是为了测试,在删除主侦听器之后,我可能会添加另一个侦听器,在出现其他问题时记录错误或警告。在发展中,这将