【问题标题】:JavaScript asynchronous race conditionJavaScript 异步竞争条件
【发布时间】:2010-11-27 04:08:33
【问题描述】:

有一组对象,这些对象通过并行 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();
                }
              });
  }
}

但是由于请求是并行执行的,因此可能会出现竞争条件。变量 number_of_requests 可以由两个“线程”同时编辑。如何避免出现竞态的机会?

【问题讨论】:

  • 如果objects 是一个对象,则没有通用的length 属性。如果它是一个数组,你不应该使用for … in,而是使用正常的计数for循环。
  • 你是对的,但你可以定义一个带有长度变量的对象。
  • JavaScript 是单线程的,因此变量不可能被两个单独的线程修改。

标签: javascript ajax asynchronous


【解决方案1】:

是否可以重新设计您的 AJAX 以使所有内容都集中在一个请求中?系统的那部分将成为最大的瓶颈并且可能会变得棘手(正如您已经发现的那样),因此您提出的请求越少越好。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 我查看了 JavaScript 规范,并没有说 JavaScript 实现必须是单线程的。
    • 关于这个问题的一些很好的答案:stackoverflow.com/questions/124764/…
    • 实际上 ECMAScript 被指定为单线程,但是如果您执行异步加载,您将按照加载完成的顺序获得回调。您可以将浏览器中的 ES 视为只有一个事件队列,任何要执行的 ES 都被推到队列的后面,并且每个事件都按顺序触发。
    【解决方案3】:

    它更复杂,但我建议使用第三个函数来监控结果。像这样的:

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

    2) 调用请求 A。

    3) 呼叫请求 B.

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

    5) 请求 A 完成 - 回调函数设置“A All Done!”价值。

    6) Monitor 识别到两个请求都已完成并调用使用来自两者的数据的函数。

    更简单地说,就是“依赖”(多次调用)到“监控”(检查依赖的函数)到“完成”(一切准备就绪时采取的行动)。

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

    您可以根据需要扩展您的依赖项。

    【讨论】:

    猜你喜欢
    • 2020-07-12
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-06
    • 2020-11-22
    • 2021-08-02
    • 1970-01-01
    相关资源
    最近更新 更多