处理一个事件上的异步执行,使用多个事件处理程序。

huangapple go评论70阅读模式
英文:

Handle asynchronous execution on one event with multiple event handlers

问题

以下是您要翻译的内容:

有一个 <input type="file"> HTML 元素,可能附加了一个或多个事件处理程序。然而,当一个事件处理程序包含异步代码时,它会停在那里,然后转到下一个事件处理程序。

使用 window.createImageBitmap 的示例:https://jsfiddle.net/mxpy5qbw/1/

如果 window.createImageBitmap 方法有同步版本,将解决这个问题。

我正在寻找一种处理方式,使第一个事件处理程序(在 JSFiddle 示例中为 onChangeEvent)在所有工作完成之前不会完成执行,然后转到下一个事件处理程序。

此外,请注意,onChangeEvent(来自示例)是自定义事件处理程序,但其他事件处理程序可能来自其他地方,不一定由我控制。

英文:

There is an <input type="file"> HTML element that may have attached 1 or more event handlers. However, when 1 event handler contains an asynchronous code then it stops at it and goes to the next event handler.

Example with window.createImageBitmap usage: https://jsfiddle.net/mxpy5qbw/1/

When method window.createImageBitmap would have the synchronous version that would resolve the issue.

I'm looking for a solution to handle it the way that the first event handler (in JSFiddle example onChangeEvent) will not complete the execution until all work is done, then go to the next event handler.

Also, note onChangeEvent (from the example) is the custom event handler, but other event handlers may come from other places, not necessarily controlled by me.

答案1

得分: 1

<!-- 开始代码片段: js 隐藏: false 控制台: true Babel: false -->

<!-- 语言: lang-js -->

    const inputFile = document.getElementById('inputFile');

    const handlers = [];

    const onChangeEvent = async (event) => {
      let imageBitmap;

      try {
        imageBitmap = await window.createImageBitmap(event.target.files[0]);
      } catch (e) {
        console.error('onChangeEvent', e);
      }

      console.log('onChangeEvent', event, imageBitmap);
    };

    inputFile.addEventListener('change', async (e)=>{
        await handlers.reduce(async (promise, handler)=>{
          await promise;
          return handler(e);
        }, Promise.resolve());
    }, { capture: true });

    handlers.push(onChangeEvent);

    const onChangeEventNext = (event) => {
      console.log('onChangeEventNext', event);
    };

    handlers.push(onChangeEventNext)


<!-- 语言: lang-html -->

    <input type="file" id="inputFile">


<!-- 结束代码片段 -->
英文:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const inputFile = document.getElementById(&#39;inputFile&#39;);

const handlers = [];

const onChangeEvent = async (event) =&gt; {
  let imageBitmap;

  try {
    imageBitmap = await window.createImageBitmap(event.target.files[0]);
  } catch (e) {
    console.error(&#39;onChangeEvent&#39;, e);
  }

  console.log(&#39;onChangeEvent&#39;, event, imageBitmap);
};

inputFile.addEventListener(&#39;change&#39;, async (e)=&gt;{
		await handlers.reduce(async (promise, handler)=&gt;{
    	await promise;
      return handler(e);
    }, Promise.resolve());
}, { capture: true });

handlers.push(onChangeEvent);

const onChangeEventNext = (event) =&gt; {
  console.log(&#39;onChangeEventNext&#39;, event);
};

handlers.push(onChangeEventNext)

<!-- language: lang-html -->

&lt;input type=&quot;file&quot; id=&quot;inputFile&quot;&gt;

<!-- end snippet -->

You can create an array of handlers and attach a common handler to execute the array of async functions one by one using array reduce method and async/await. See the attached snippet.

答案2

得分: 0

最终解决方案是停止传播,存储事件细节,执行您的任务,并在相同的目标元素上分派相同的事件。考虑到这一点,您需要跳过自己的事件处理程序,以避免无限循环。所有细节都在以下文章中描述:

https://www.sitelint.com/blog/how-to-pause-and-resume-event-propagation-in-javascript/

英文:

The final solution is to stop propagation, store event details, execute your task, and dispatch the same event on the same target element. With that in mind, you need to skip your own even handler to avoid an infinite loop. All details are described in the following article:

https://www.sitelint.com/blog/how-to-pause-and-resume-event-propagation-in-javascript/

huangapple
  • 本文由 发表于 2023年7月6日 15:03:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76626256.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定