当前位置:  开发笔记 > 编程语言 > 正文

避免javascript竞争条件

如何解决《避免javascript竞争条件》经验,为你挑选了2个好方法。

这是场景:

我的用户被呈现为网格,基本上是电子表格的精简版本.网格中的每一行都有文本框.当他们更改文本框中的值时,我正在对其输入执行验证,更新驱动网格的集合,并重新绘制页面上的小计.这全部由每个文本框的OnChange事件处理.

当他们点击"保存"按钮时,我正在使用按钮的OnClick事件对金额执行一些最终验证,然后将他们的整个输入发送到Web服务,保存它.

至少,如果他们将表单选中到"提交"按钮,则会发生这种情况.

问题是,如果他们输入一个值,那么立即单击保存按钮,SaveForm()在UserInputChanged()完成之前开始执行 - 一个竞争条件.我的代码不使用setTimeout,但我用它来模拟缓慢的UserInputChanged验证代码:

 
 

Amount:  
Subtotal:


Saved amount:

我不认为我可以加快验证代码 - 它非常轻量级,但显然,代码试图在验证完成之前调用Web服务的速度足够慢.

在我的机器上,〜95ms是验证代码在保存代码开始之前执行之间的幻数.根据用户的计算机速度,这可能更高或更低.

有没有人有任何想法如何处理这种情况?同事建议在验证代码运行时使用信号量,并在保存代码中使用繁忙循环等待信号量解锁 - 但我想避免在我的代码中使用任何类型的繁忙循环.



1> zaratustra..:

使用信号量(让我们称之为StillNeedsValidating).如果SaveForm函数看到StillNeedsValidating信号量已启动,请让它激活自己的第二个信号量(我在这里称之为FormNeedsSaving)并返回.验证函数完成后,如果FormNeedsSaving信号量已启动,它将自行调用SaveForm函数.

在jankcode;

function UserInputChanged(control) {
    StillNeedsValidating = true;
    // do validation
    StillNeedsValidating = false;
    if (FormNeedsSaving) saveForm(); 
}

function SaveForm() {
    if (StillNeedsValidating) { FormNeedsSaving=true; return; }
    // call web service to save value
    FormNeedsSaving = false;
}



2> Andrew Rolli..:

验证期间禁用保存按钮.将其设置为禁用,作为验证的第一件事,并在完成后重新启用它.

例如

function UserInputChanged(control) {
    // --> disable button here --< 
    currentControl = control;
    // use setTimeout to simulate slow validation code (production code does not use setTimeout)
    setTimeout("ValidateAmount()", 100); 
}

function ValidateAmount() {
    // various validationey functions here
    amount = currentControl.value; // save value to collection
    document.getElementById("Subtotal").innerHTML = amount; // update subtotals
    // --> enable button here if validation passes --<
}

你必须在删除setTimeout时调整并使验证成为一个函数,但除非你的用户有超人的反应,否则你应该好好去.

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有