我试图在我的工作流程中加入CustomEvent。 但我需要以两种方式进行通信:脚本将事件发送到文档,它应该响应同一个启动器。
我尝试了以下方面的内容:
ev = new CustomEvent('StorageRequest', {
detail: {
space: theSpace,
method: theMethod,
arguments: args
}
})
document.dispatchEvent(ev)
我的听众看起来像这样:
document.addEventListener('StorageRequest', (e) => {
console.debug('Sending StorageRequest', e)
// do something, then answer back with response
})
实现这一目标的方法是什么?
我尝试过使用Promise并使用resolve / reject发送响应,但是传递函数似乎打破了事件中的detail
,如果我尝试这样做,结果是null:
return new Promise((resolve, reject) => {
ev = new CustomEvent('StorageRequest', {
detail: {
space: theSpace,
method: theMethod,
arguments: args,
resolve, reject
}
})
document.dispatchEvent(ev)
})
备注: 我想避免"一般地"将响应发送回文档。我更喜欢请求和响应是完全有意的,并且在代码中正确处理 我没有附加元素,所以使用
e.target
中的元素不是一个选项(除非我可以用它做其他事情)
答案 0 :(得分:1)
你不能回应"在DOM事件中 - 它们只是向上传播DOM树,直到达到顶层。
承诺可能有效,设置正确,但您只能回复一次。一旦承诺得到解决/拒绝,您无法再次解决或拒绝承诺,它将忽略后续的解决/拒绝呼叫。
作为替代方案,您可以设置2个单独的事件并响应第一个应该实现您尝试的事件:
sReqEvent = new CustomEvent('StorageRequest', {
detail: {
space: theSpace,
method: theMethod,
arguments: args
});
console.debug('Sending StorageRequest');
document.dispatchEvent(sReqEvent);
监听器:
document.addEventListener('StorageRequest', (e) => {
// do something, then answer back with response
var sRespEvent = new CustomEvent('StorageResponse', e.data);
console.debug('Sending StorageResponse', e.data);
document.dispatchEvent(sRespEvent);
});
document.addEventListener('StorageResponse', (e) => {
// This is my response
});
当然这是不必要的,您可以使用" StorageResponse"从StorageRequest侦听器中调用的函数...
另一个替代方法是使用window.postMessage
,但更多涉及使用单独的后向/后请求进行设置,IE9将仅支持传递的字符串(如果需要,您需要在IE9中对JSON进行编码/解码发送除字符串以外的任何内容 - 工作,但如果您在所有浏览器中将其作为全局变通方法执行,则速度会慢一些。)