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

Javascript / dojo - how to prevent async calls issue? RACE condition due to dojo widget calls

我们有一个门户网站,当用户提交表单时,在填写所有必填详细信息后,UI 是必填字段之一的 posting null/空值 - “姓名”到服务器 API.

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

有一个 submit() 方法,在单击此表单上的“提交”按钮时触发。此方法 post 将员工对象作为负载发送到服务器 API。

问题:

当用户在名称文本框中键入内容,并在不松开焦点的情况下单击“提交”按钮。 这会触发两个异步方法(onFocusOut()submit() 方法),它们之间的间隔只有几分之一毫秒。

在极少数情况下,submit() 是 post 将员工对象发送到服务器 API,在名称 [=66= 之前] 的员工对象由 onFocusOut() 方法更新。

解决方案?

这里有针对此问题的不同可能解决方案 –

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

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

1。使用 setTimeout() 延迟 submit() 调用

这绝对是防止这种情况发生的一种选择,但也有一些注意事项。

当您将 submit() 包裹在 setTimeout() 中(或者更确切地说,将其用作 setTimeout() 中的 callback 时,会发生什么event queue.

这样 submit() 肯定会延迟,但它最终会使您的代码减慢相当大的幅度,具体取决于在 submit().[=33= 之前堆叠的其他函数调用]

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

2。使用 onChange() 事件而不是 onFocusOut()

在我看来,这是迄今为止解决您的问题的更好选择。

React中,此方法用于创建所谓的controlled components。随着对 input 的每次更改,都会调用一个函数,用新值更新 state。这个新值然后用于重新渲染组件(由于它检测 DOM 中的变化的方式,这在 React 中非常有效)。

这里有一个很好的解释:

由于您正在使用某种 model/object 来存储值,这可能是您的最佳选择。

3。在发送数据之前使用验证函数

嗯,这也可能是一个很好的解决方案,尤其是当您将函数设计为 Promise 时,但在采用这种方法之前需要考虑一些事项。

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

其次还有一个问题,你需要多走一步才能成功post数据到API,这总是有机会产生bug/several错误在你的代码中。


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

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

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