具有响应的CustomEvent,这可能吗?

时间:2017-09-19 15:00:58

标签: javascript events

我试图在我的工作流程中加入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中的元素不是一个选项(除非我可以用它做其他事情)

1 个答案:

答案 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进行编码/解码发送除字符串以外的任何内容 - 工作,但如果您在所有浏览器中将其作为全局变通方法执行,则速度会慢一些。)