【问题标题】:Race Condition because of multiple AJAX requests由于多个 AJAX 请求而导致的竞争条件
【发布时间】:2009-08-14 07:53:11
【问题描述】:

我的问题如下。我编写了一个类 AJAXEngine,它在构造函数中创建了一个新的 XMLHttpRequest 对象。该类包含一个名为 responseAnalyser 的方法,当 XMLHttpRequest 对象的“onreadystatechange”发生变化时调用该方法。 所以现在我创建了 4 个 AJAXEngine => 4 XMLHttpRequest 对象的实例。

现在我有另一个类 DataRequester,它有一个数组属性 dataReq,它保存 AJAXEngine 的实例。整个程序中只有一个DataReqeuster实例! DataRequester 有一个名为 callWhenFinished 的函数。该函数被函数调用 AJAXEngine 的 responseAnalyser 并减少 DataRequester 实例的变量。

但是,我认为会发生竞争条件。我如何在 JavaScript 中预防它们?

function AJAXEngine
{
 this.httpReqObj = //create new XMLHttpRequest Object
 this.obj;
 this.func;
}
AJAXEngine.prototype.responseAnalyser = function()
{
 if(this.httpReqObj.readState == 4)
 {
  this.func.call(this.obj);
 }
}
AJAXEngine.prototype.fireReq = function(o, f)
{
 this.obj = o;
 this.func = f;
 // fire ajax req
}

function DataRequester()
{
 this.dataReq = new Array();
 this.test = 4;

 for(var i = 0; i < 4; i ++)
 {
  this.dataReq[i] = new AJAXEngine();
 }
}
DataRequester.prototype.callWhenFinished = function()
{
 this.test --;
}

【问题讨论】:

    标签: javascript ajax xmlhttprequest race-condition


    【解决方案1】:

    不确定这是否有帮助,但您似乎正在尝试创建托管连接池。几年前我做了一个,在这里仍然可以正常工作:

    DP_RequestPool Library

    池确保使用您定义的尽可能多的同时请求(受系统限制)按照您提供的顺序发出请求(当然,它们可能会根据性能以任何顺序返回)。您可以为不同的目的实例化多个池。

    如果没有别的,这可能会给你一些想法。

    【讨论】:

    • 你能给我链接吗?
    • 链接在答案中 - 你有问题吗?这里没有标记:depressedpress.com/Content/Development/JavaScript/Extensions/… 下载链接在页面的第一部分。
    • 嗨,是的,我有问题。每次单击链接时,我都会看到一个蓝色框,标题为“处理请求时发生错误”元素 DP 在类型为 [Ljava.lang.String; 的 Java 对象中未定义;引用为
    • 对不起 - 我这边的愚蠢错误(我刚刚将我的网站移动到了新的服务器/ColdFusion 版本,但未能为新用户更改指针)。它现在应该可以工作了。上面的链接应该可以访问文档,但代码的链接具体是:depressedpress.com/Content/Development/JavaScript/Extensions/… 很抱歉让我感到沮丧,但感谢您指出我的愚蠢!
    【解决方案2】:

    首先:大多数面向 AJAX 的浏览器都支持“只有 2 个同时请求到同一个域”的约定。因此,如果您开始 4 个,则其中 2 个将被挂起。

    您的 DataReqeuster /singleton/ 可以拥有变量“test”的数组,因此不要在多个实例之间共享单个变量,而是创建多个数据实例。因此,要计算结果,您需要对“测试”数组求和。

    【讨论】:

      【解决方案3】:

      你需要实现一个临时的互斥锁(想法是启发式会检查一个布尔值,如果它是假的则将其设置为真,然后执行正文,否则睡眠(settimeout?) - 这显然是一个非常糟糕的启发式,没有人会实现,因为它不是线程安全的,但这是无论如何处理竞争条件的一般概念)。

      我相信至少有一个在网络上创建互斥锁的示例,但我没有详细查看它 - 它有一些批评者,但我不知道在 javascript 中实现“线程安全”的另一种方法。我从来不需要实现 js 的“线程安全”,但那是我开始寻找是否必须在 javascript 中处理竞争条件。

      【讨论】:

        【解决方案4】:

        你不能在 javascript 中做一个互斥锁,因为确实没有内置的睡眠功能可用。

        见:Is there an equivalent Javascript or Jquery sleep function?

        此外,没有办法确保互斥体中的布尔标志不会与另一个线程同时被访问,布尔值本身需要一个互斥体......等等。您需要类似 Java 中的 Synchronized 关键字才能在 javascript 中使用,而这根本不存在。我曾遇到过担心线程安全的情况,但无论如何使用代码时,如果发生错误但尚未发生,则有替代计划。

        所以我的建议是,如果您遇到错误,可能不是因为竞争条件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-05-16
          • 2011-12-20
          • 2022-11-18
          • 1970-01-01
          • 2020-08-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多