Javascript 处理可能是异步的动态脚本

Javascript 处理可能是异步的动态脚本,javascript,typescript,asynchronous,Javascript,Typescript,Asynchronous,我们有一个应用程序,它让我们的用户能够在特定的“钩子”点编写自己的脚本。示例场景如下所示: 我们提供2个表单字段 用户可以添加自定义行为以在每个“获得焦点”和“失去焦点”事件上运行 用户编写一个自定义脚本,在第一个字段的“焦点丢失”处,他执行一些关于该字段值的验证逻辑 如果验证为false,那么我们的应用程序必须阻止字段更改,并强制选择保留在现有字段上,直到提供有效值为止 如果验证逻辑是简单同步的,比如正则表达式匹配测试,那么这个场景很容易处理。但是,如果用户添加了一些异步逻辑(例如,验证规

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

  • 我们提供2个表单字段
  • 用户可以添加自定义行为以在每个“获得焦点”和“失去焦点”事件上运行
  • 用户编写一个自定义脚本,在第一个字段的“焦点丢失”处,他执行一些关于该字段值的验证逻辑
  • 如果验证为false,那么我们的应用程序必须阻止字段更改,并强制选择保留在现有字段上,直到提供有效值为止
如果验证逻辑是简单同步的,比如正则表达式匹配测试,那么这个场景很容易处理。但是,如果用户添加了一些异步逻辑(例如,验证规则可能由web服务提供),会发生什么情况?那么,您将如何处理
onfeldfocuslost
hook函数呢?使其
async
将迫使我们将
await
链一直传播到调用堆栈的顶部,直到调用顺序无关紧要的那一点,这一点上可能有很多层(这些层已经实现了,需要更改)

请注意,我们使用的是
Typescript
,并将其编译为ES5,与IE10+具有所需的兼容性(所有
wait
generator
可以像正常情况一样进行多填充)

最简单的例子:

// 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)
});

一种可能的解决方案是检查钩子是否返回承诺,如果是,则阻塞字段,直到承诺返回:

 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);
    }
 });

您可以添加一个吗?描述的场景非常有说明性,但是在这里您不能从回调中
返回
!我知道,这只是为了解释目标是什么。javascriptAdd不是完全有效的,如果使用具有通过/失败输入的async,则添加他们可以调用的回调函数。正如问题描述中所解释的,这是我们已经实现的,但这需要所有调用堆栈到该点都成为可等待的,可以达到10层up@konstantine你现在期望的结果是什么?一些使异步代码同步的神奇代码?这是不存在的……我正在提出一个问题,并根据一些要求寻求解决方案。如果不存在这样的解决方案,这也是一个可以接受的答案。@konstantine解决方案将是重构。然而,你为什么还要等10层呢?还有其他的逻辑吗?不能由
focustoremainField
及其对应项触发吗?这真的需要异步吗?这里当然有很多额外的逻辑没有概述。应用程序很复杂,当用户在表单字段中移动时,会在后台发生很多事情。另外,由于用户被告知他可以在浏览器上下文中用Javascript编写自定义脚本逻辑,因此他希望能够执行异步逻辑,因为JS现在就可以做到这一点。
 async function hook(){
   const res = await fetch("someapi");
   return res === "success";
}