我正在开发一个chrome扩展程序,该扩展程序使用chrome的运行时sendMessage API在扩展程序和内容脚本所插入的页面之间来回发送一次消息。问题是我需要一些消息来优先处理该系统。我已经实现了一个自定义端口来执行优先级消息传递,但是我似乎无法使用端口解决方案来复制sendResponse
API。
流程
客户端调用一个方法,该方法返回一个promise,该方法存储请求和resolve方法的随机数,通过parent.postMessage({data}, '*')
向其父级发送一条消息,然后在window
s {{1 }}侦听器将使用包含相同随机数的数据进行调用。
扩展程序的内容脚本侦听消息:
message
,然后背景页充当连接的另一端
const port = chrome.runtime.connect({name: 'priorityPort'})
function getResponse(data) {
return new Promise((resolve, reject) => {
if (priority) {
port.postMessage({data})
port.onMessage.addListener(msg => {
resolve(msg)
})
} else {
chrome.runtime.sendMessage({data}, resolve)
}
})
}
window.addEventListener('message', async event => {
const response = await getResponse(event.data)
event.source.postMessage({response})
})
但是,这不会像// normal
chrome.runtime.onMessage.addListener((obj, sender, sendResponse: data => {
;(async () => {
sendResponse({ status: 'success', body })
})()
return true
})
// priority
chrome.runtime.onConnect.addListener((port) => {
;(async () => {
port.onMessage.addListener(async msg => {
port.postMessage({ status: 'successs', body })
})
})()
return true
})
那样将响应返回给请求者。任何帮助是极大的赞赏。
答案 0 :(得分:0)
您可以创建一个队列,如下所示:
class Queue {
constructor() {
this.arr = [];
this.awaiting = [];
}
enqueue(msg) {
if (this.awaiting.length) {
this.awaiting.shift()(msg)
}else {
this.arr.push(msg)
}
}
dequeue() {
if (this.arr.length) {
return this.arr.shift()
}
return new Promise(resolve => {
this.awaiting.push(resolve);
});
}
}
这是您的用法:
const queue = new Queue();
const port = chrome.runtime.connect({name: 'priorityPort'})
port.onMessage.addListener(msg => {
queue.enqueue(msg);
})
window.addEventListener('message', async event => {
port.postMessage({date: event.data})
const response = await queue.dequeue()
event.source.postMessage({response})
})
您可以开发某种通信协议,并具有多个队列来处理不同类型的消息。在端口的消息侦听器中,检查消息的类型并将其添加到适当的队列中。
这只是一个主意,我不确定您要做什么,我可能已经针对您的用例使这种方式变得复杂了。