JavaScript异步竞争条件

JavaScript异步竞争条件,javascript,ajax,asynchronous,Javascript,Ajax,Asynchronous,有一组对象,它们通过并行ajax请求进行扩展。当最后一个请求完成时,应处理数组。我看到的唯一解决方案是: function expandArray(objects, callback){ number_of_requests=objects.length-1; for(i in objects){ $.getJSON(request,function(){ //expanding array i

有一组对象,它们通过并行ajax请求进行扩展。当最后一个请求完成时,应处理数组。我看到的唯一解决方案是:

function expandArray(objects, callback){
  number_of_requests=objects.length-1;
  for(i in objects){
    $.getJSON(request,function(){
                //expanding array           
                if(--number_of_reuests==0){
                  callback();
                }
              });
  }
}

但由于请求是并行执行的,所以有可能出现竞争条件。两个“线程”可以同时编辑可变数量的请求。如何避免比赛条件的机会

Javascript不是单线程的吗?您所说的那种情况不会发生。

是否可以重新编写AJAX,以便在一个请求中完成所有操作?系统的这一部分将是最大的瓶颈,并且可能会变得棘手(正如您所发现的),因此您提出的请求越少越好


我唯一能想到的另一种方法是,如果每个请求都改变了它的相关对象,设置了一个标志值或其他什么,然后你循环遍历所有对象,检查是否所有标志都已设置。

这更复杂,但我建议使用第三个函数来监视结果。大概是这样的:

1) 启动监视器-使用一个适当的间隔监视器(在这里使用一个间隔来测试很重要-一个简单的循环会将JS引擎锁紧)来监视请求a和B的结果

2) 打电话请求A

3) 呼叫请求B

4) 请求B完成-回调函数设置“B全部完成!”值

5) 请求完成-回调函数设置“全部完成!”值

6) 监视器识别两个请求都已完成,并调用使用来自这两个请求的数据的函数

更简单地说,这是“依赖项”(多次调用)“监控”(检查依赖项的函数)到“完成”(一切就绪时要采取的操作)

您可以将回调和完成函数创建为嵌套函数,以维护封装并减少全局范围中的“小”


您可以随心所欲地扩展依赖项。

如果
对象
是一个对象,则没有通用的
长度
属性。如果它是一个数组,你不应该在中对…使用
,而应该在
循环中使用正常计数
。你是对的,但也有可能用一个长度变量定义一个对象。JavaScript是单线程的,因此不可能由两个单独的线程修改该变量。我已经看过JavaScript规范,没有人说JavaScript实现必须是单线程的。关于这个问题,有一些很好的答案:实际上ECMAScript被指定为单线程,但是如果执行非同步加载,则将按照加载完成的顺序获得回调。您可以将浏览器中的ES想象为只有一个事件队列,任何要执行的ES都被推到队列的后面,并且每个事件都被顺序触发。提供一个名为的函数,该函数执行步骤1-6。