Javascript / dojo - 如何防止异步调用问题?由于dojo小部件调用导致的RACE条件

时间:2018-02-16 06:22:40

标签: javascript architecture dojo race-condition

我们有一个门户网站,当用户提交表单后,在填写所有必填详细信息后,UI会将一个必填字段 - “名称”的空/空值发布到服务器API。

Name是一个文本框(dojo小部件),它处理了onFocusOut()方法。此方法执行一些检查/序列化/反序列化并异步更新主对象的Name属性,说“employee”。

有一个submit()方法,点击此表单上的“提交”按钮即可触发。此方法将employee对象作为有效负载发布到服务器API。

ISSUE:

当用户在名称文本框中键入内容时,无需忽略焦点,单击“提交”按钮。 这会触发两个异步方法(onFocusOut()submit()方法),仅相隔几分之一毫秒。

在一些罕见的情况下,submit()将员工对象发布到服务器API,然后通过onFocusOut()方法更新员工对象的Name属性。 < /强>

解?

以下是此问题的不同可能解决方案 -

  • 使用setTimeout()延迟触发submit()方法。
  • 使用onChange()而不是onFocusOut()的文本框更新模型。
  • 进行函数调用以在submit()方法API发布之前立即检查所有验证。
  • 使用班级标志。在onFocusOut()方法的开头和结尾设置它开/关。提交等待设置此标志,然后执行API post。

这种RACE条件的最佳解决方案是什么?在dojo应用程序中处理这种情况的最佳实践是什么?

2 个答案:

答案 0 :(得分:1)

竞赛条件是JavaScript中最难解决的问题,所以这是一个很好的问题。你提供的解决方案确实指向了正确的方向,所以让我看看其中的三个,看看我是否可以为此提供任何帮助。

<强> 1。使用setTimeout()延迟submit()来电

这绝对是防止这种情况的一种选择,但有一些警告。

当您将submit()包裹在setTimeout()中(或者更确切地将其用作callback中的setTimeout())时,会发生的事情是提交内容会叠加到event queue上1}}。

这样submit()肯定会被延迟,但最终可能会使代码速度变慢,具体取决于在submit()之前堆叠的其他函数调用。

我不知道你是否熟悉JavaScript如何处理函数调用和事件,但是有一些关于这个主题的非常有用的资源可以在网上找到。以下是菲尔罗伯茨关于它的一个讲话,它帮助我更好地理解它:What the heck si the event loop anyway?

<强> 2。使用onChange()事件代替onFocusOut()

在我看来,这是解决问题的最佳选择。

React中,此方法用于创建所谓的controlled components。对input的每次更改都会调用一个函数,该函数使用新值更新state。然后,此新值将用于重新呈现组件(由于它检测到React中的更改的方式,因此在DOM中非常有效。)

在SO上可以找到一个很好的解释:controlled VS uncontrolled components

由于您使用某种模型/对象来存储值,因此这可能是您的最佳选择。

第3。在发送数据之前使用验证功能

嗯,这也是一个很好的解决方案,特别是当你将函数设计为Promise时,但在采用这种方法之前还有一些事情需要考虑。

首先,您需要使用某种模型来检查所有输入是否正确并符合预期。这可能对用户的意图非常不安全,并可能导致用户体验不满意。

其次,还有一个问题是您需要再采取一个步骤才能将数据成功发布到API,这总是有机会在代码中产生错误/错误。

TL:DR; 我会选择选项2 ,因为它是您解决方案中最安全的。

我希望我能对此有所帮助。 :d

答案 1 :(得分:0)

在输入上设置intermediateChanges: true可以解决这些问题。 https://davidwalsh.name/dijit-intermediatechanges