英文:
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('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)
<!-- language: lang-html -->
<input type="file" id="inputFile">
<!-- 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/
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论