0

我的问题如下。我编写了一个类 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 --;
}
4

4 回答 4

1

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

DP_RequestPool 库

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

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

于 2009-08-17T14:56:47.493 回答
0

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

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

于 2009-08-14T08:56:02.280 回答
0

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

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

于 2009-08-14T08:16:28.240 回答
0

您不能仅仅因为没有内置的睡眠功能可用而在 javascript 中执行互斥锁。

请参阅:是否有等效的 Javascript 或 Jquery 睡眠功能?

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

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

于 2009-08-14T19:55:01.783 回答