我们有一个应用程序,可以让我们的用户能够在特定的“钩子”点编写自己的脚本。示例场景如下:
如果验证逻辑像正则表达式匹配测试一样简单且同步,则此方案很容易处理。但是,如果用户添加了一些异步逻辑会发生什么(验证规则可能由Web服务提供)?那么你如何处理onFieldFocusLost
钩子函数呢?使它async
将迫使我们将await
链一直传播到调用堆栈的顶部,直到调用序列无关紧要的点,这可能是很多层(已经实施并且很难改变)。
请注意,我们正在使用Typescript
并将其编译为ES5,并且与IE10 +具有必需的兼容性(所有await
和generator
shenanigans都可以正常填充。
最小例子:
// hook function whose implementation is provided by the user
function onFocusLost(field) {
// implementation A
return validRegex.test(field.value);
// implementation B
doXHR('/validRegex', 'GET', function(validRegex) {
return validRegex.test(field.value);
});
}
// hook function called by our application
inputField.addEventListener('focus-lost', function() {
if (!onFocusLost(inputField)) {
forceFocusToRemainOnField(inputField);
return;
}
giveFocusToNextField(); // this must not be called if the user's onFocusLost logic returns false (synchronously or not)
});
答案 0 :(得分:1)
一个可能的解决方案是检查钩子是否返回Promise,如果是,则阻止该字段,直到promise返回:
inputField.addEventListener('focus-lost', async function(){
const hook: boolean | Promise<boolean> = onFocusLost();
if(hook instanceof Promise){
forceFocusToRemainOnField(inputField);
alert("We are checking your input! Please wait");
hook = await hook;
}
if(hook){
//release field somehow
} else {
forceFocusToRemainOnField(inputField);
}
});
所以钩子看起来像这样:
async function hook(){
const res = await fetch("someapi");
return res === "success";
}