Javascript/dojo-如何防止异步调用问题?dojo小部件调用导致的竞争条件
我们有一个web门户,当用户提交表单时,在填写所有必需的详细信息后,UI会将其中一个必填字段“Name”的空/空值发布到服务器API Name是一个文本框(一个dojo小部件),它处理了Javascript/dojo-如何防止异步调用问题?dojo小部件调用导致的竞争条件,javascript,architecture,dojo,race-condition,Javascript,Architecture,Dojo,Race Condition,我们有一个web门户,当用户提交表单时,在填写所有必需的详细信息后,UI会将其中一个必填字段“Name”的空/空值发布到服务器API Name是一个文本框(一个dojo小部件),它处理了onFocusOut()方法。此方法执行一些检查/序列化/反序列化,并异步更新主对象的Name属性,例如“employee” 有一个submit()方法,单击此表单上的提交按钮会触发该方法。此方法将employee对象作为有效负载发布到服务器API 问题: 当用户在名称文本框中键入时,在不失去焦点的情况下单击提交
onFocusOut()
方法。此方法执行一些检查/序列化/反序列化,并异步更新主对象的Name属性,例如“employee”
有一个submit()
方法,单击此表单上的提交按钮会触发该方法。此方法将employee对象作为有效负载发布到服务器API
问题:
当用户在名称文本框中键入时,在不失去焦点的情况下单击提交按钮。
这将触发两个异步方法(onFocusOut()
和submit()
方法),它们之间的间隔仅为几分之一毫秒
在一些罕见的情况下,submit()
在员工对象的Name属性被onFocusOut()更新之前,将员工对象发布到服务器API。
解决方案
以下是该问题的不同可能解决方案——
- 使用
延迟触发setTimeout()
方法李>submit()
- 使用文本框的
而不是onChange()
更新模型李>onFocusOut()
- 在
方法API post之前立即进行函数调用以检查所有验证李>submit()
- 使用类级别标志。在
onFocusOut()方法的开始和结束时将其设置为开/关。Submit等待设置此标志,然后执行API post
对于这种竞争条件,什么是最佳解决方案?在dojo应用程序中处理这种情况的最佳实践是什么?竞争条件是
JavaScript
中最难解决的问题,因此这是一个好问题。您为此提供的解决方案确实指向了正确的方向,所以让我来介绍其中的三个,看看我是否能在这方面提供帮助
1。使用setTimeout()
延迟submit()
调用
这绝对是防止这种情况的一种选择,但也有一些注意事项
当您将submit()
包装在setTimeout()
中(或者更确切地说,将其用作setTimeout()
中的回调
)时,会发生的情况是提交被堆叠到事件队列中
这样一来,submit()
肯定会延迟,但它最终会使代码的速度降低相当大的幅度,这取决于在submit()
之前堆积的其他函数调用
我不知道您是否熟悉JavaScript
如何处理函数调用和事件,但是可以在网上找到一些关于这个主题的非常有用的资源。以下是Phil Roberts关于它的谈话,它帮助我更好地理解它:
2。使用onChange()
事件代替onFocusOut()
在我看来,这是解决你问题的更好的选择
在React
中,此方法用于创建所谓的受控组件
。对输入的每次更改
都会调用一个函数,用新值更新状态
。然后使用此新值重新加载组件(由于它检测DOM
中的更改,因此在React
中非常有效)
这里有一个很好的解释:
由于您使用某种模型/对象来存储值,因此这可能是您的最佳选择
3。发送数据前使用验证功能
<>这可能是一个很好的解决方案,尤其是当你把你的函数设计成Engult时,但是在采用这种方法之前还有一些事情要考虑。
首先,您需要某种模型来检查每个输入是否正确,是否符合预期。这对于用户的意图来说是非常不安全的,并可能导致用户体验不满意
第二个问题是,您需要再采取一个步骤来成功地将数据发布到API
,它总是有机会在代码中产生一个或多个bug
TL:DR;
我会选择选项2,因为它是您的解决方案中最安全的
我希望我能在这方面有所帮助D在输入上设置中间更改:true
,应该可以解决这些问题。
请向我们提供显示此行为的代码。。。当我们能真正看到这里发生的事情时,帮助你会更容易。@MichelEngelen,由于保密条款,我不能发布代码。好的,我会尽量回答你的问题,没有示例代码