为了为软件开发插件,我需要听一听dispatchEvent生成的事件,并在接收到此事件时执行一些操作。重要的是,在软件在dispatchEvent之后继续执行代码之前,我的操作应该完成。
因为dispatchEvent是同步的,所以应该是.不幸的是,我的操作是异步的(基本上我需要等待视频被查找),在这种情况下,dispatchEvent会在我自己的代码结束之前继续运行。当被调用的函数是异步的时,是否也可以获得dispatchEvent的同步行为?
示例:
我想要下面的代码来生成输出:
Putting the clothes in the washing machine.
Machine started...
Machine ended...
Picking the washed clothes.不幸的是,这些衣服是在洗衣机结束前挑选的:
Putting the clothes in the washing machine.
Machine started...
Picking the washed clothes.
Machine ended...我使用了这个代码:
var button = document.getElementById('button');
button.addEventListener('click', event => {
console.log("Putting the clothes in the washing machine.");
const machineResult = button.dispatchEvent(new CustomEvent('startmachine', {
'detail': {
timeProgram: 3000
}
}));
if (machineResult.defaultPrevented) {
console.log("Picking the dirty clothes.");
} else {
console.log("Picking the washed clothes.");
}
});
button.addEventListener('startmachine', async event => {
console.log("Machine started...");
await new Promise(r => setTimeout(r, event.detail.timeProgram));
console.log("Machine ended...");
});<button id="button">Wash my clothes</button>
编辑:找到一个我不喜欢的肮脏解决方案
显然,这似乎是不可能的,我使用了一种不同的方法,即unfortunately需要在代码dispatchEvent之后进行一些更改(因为我不负责代码的这一部分,所以我更喜欢在dispatchEvent之后不更改代码的方法)。
这样做的目的是在事件中添加一个数组,每个侦听器都可以在其中放置一个异步函数。然后,在dispatchEvent完成后,代码将执行该数组中的所有函数,如果有任何函数返回false,则会认为该事件已被中止。
var button = document.getElementById('button');
button.addEventListener('click', async event => {
console.log("Putting the clothes in the washing machine.");
var listOfActions = [];
const machineResult = button.dispatchEvent(new CustomEvent('startmachine', { 'detail': {timeProgram: 3000, listOfActions: listOfActions} }));
results = await Promise.all(listOfActions.map(x => x()));
if (machineResult.defaultPrevented || !results.every(x => x != false)) { // Do not use == true or boolean to ensure returning nothing does not abort.
console.log("Picking the dirty clothes.");
} else {
console.log("Picking the washed clothes.");
}
});
button.addEventListener('startmachine', event => {
event.detail.listOfActions.push( async () => {
console.log(">>> Machine started...");
await new Promise(r => setTimeout(r, event.detail.timeProgram));
console.log("<<< Machine ended...");
// If you want to say that the clothes are dirty:
// return false
});
});<button id="button">Wash my clothes</button>
编辑2
使用允诺更好地处理错误:
var button = document.getElementById('button');
button.addEventListener('click', async event => {
console.log("Putting the clothes in the washing machine.");
var listOfActions = [];
let cancelled = !button.dispatchEvent(new CustomEvent('startmachine', { 'detail': {timeProgram: 3000, listOfActions: listOfActions} }));
results = await Promise.all(listOfActions);
// Do not use == true or boolean to ensure returning nothing does not abort.
cancelled = cancelled || !results.every(x => x != false)
if (cancelled) {
console.log("Picking the dirty clothes.");
} else {
console.log("Picking the washed clothes.");
}
});
button.addEventListener('startmachine', event => {
event.detail.listOfActions.push((async () => {
console.log(">>> Machine started...");
await new Promise(r => setTimeout(r, event.detail.timeProgram));
console.log("<<< Machine ended...");
// If you want to say that the clothes are dirty:
//return false
})());
// ^-- The () is useful to push a promise and not an async function.
// I could also have written let f = async () => { ... }; event....push(f())
});<button id="button">Wash my clothes</button>
发布于 2022-01-19 09:54:31
当被调用的函数是异步的时,
是否也可以获得
dispatchEvent的同步行为?
不,不是的。
的思想是在每个侦听器可以放置一个
async function的事件中添加一个数组。然后,在完成dispatchEvent之后,代码将执行该数组中的所有函数。
是的,这是个好主意。然而,我要使它成为一系列的承诺,而不是一系列的函数。
web平台API在ExtendableEvent中使用相同的模式。不幸的是,该构造函数仅在服务工作人员内部可用:-/
https://stackoverflow.com/questions/70767676
复制相似问题