处理可能异步的动态脚本

问题描述 投票:0回答:1

我们有一个应用程序,为我们的用户提供在特定“钩子”点编写自己的脚本的能力。示例场景如下:

  • 我们提供2个表单字段
  • 用户可以添加自定义行为以在每个“Focus Gained”和“Focus Lost”事件上运行
  • 用户将自定义脚本写入第一个字段的“Focus Lost”,并执行关于该字段值的一些验证逻辑
  • 如果验证为假,那么我们的应用程序必须阻止字段更改并强制选择保留在现有字段上,直到提供有效值为止

如果验证逻辑像正则表达式匹配测试一样简单和同步,则这种情况很容易处理。但是,如果用户添加了一些异步逻辑会发生什么(验证规则可能由Web服务提供)?那么你如何处理onFieldFocusLost钩子函数呢?使它成为async然后将迫使我们将await链一直传播到调用堆栈的顶部,直到调用序列无关紧要的点,这可能是很多层(已经实现并且将会变得痛苦)。

请注意,我们正在使用Typescript并将其编译为ES5,并且与IE10 +具有所需的兼容性(所有awaitgenerator 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)
});
javascript typescript asynchronous
1个回答
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";
}
© www.soinside.com 2019 - 2024. All rights reserved.