【问题标题】:Can this ever be a race condition? (JavaScript)这可能是比赛条件吗? (JavaScript)
【发布时间】:2014-12-25 18:25:24
【问题描述】:

我正在寻找关于以下 JavaScript 代码是否包含竞争条件的可靠答案。

问题归结为:如果我开始监听异步任务的完成(例如 AJAX 调用)在我启动任务之后立即,该任务能否在我之前完成?已经开始听了吗?

我找到了几个similar questions,但没有一个答案似乎完全具体(“那里可能是个问题......不太可能 ...”)。这是我所指的那种情况的粗略示例:

// Publish an event synchronously
function emit(key){}

// Subscribe to an event
function on(key, cb){}

// Request the given url;
// emit 'loaded' when done
function get(url) {
  http.get(url, function() {
    emit('loaded');
  });
}

get(url);

on('loaded', function() {
  // Assuming this subscription happens
  // within the same execution flow as
  // the call to `get()`, could 'loaded'
  // ever fire beforehand?
});

如果答案得到实际语言规范(或其他权威来源)的支持,那就更好了!

【问题讨论】:

    标签: javascript asynchronous


    【解决方案1】:

    不,不能有竞争条件。

    异步任务可以在您开始监听事件之前完成,但这并不重要。任务的完成会创建一个事件,直到函数(或代码块)结束并将控制权返回给浏览器时才会处理该事件。

    【讨论】:

      【解决方案2】:

      @Guffa 是正确的。但是,至少在两种情况下您可以出现竞态条件。

      可能在未处理的 ajax 请求期间存在错误。考虑一些典型的 XMLHttpRequest 代码:

      var request = new XMLHttpRequest();
      request.onreadystatechange = function() {
          if (request.readyState === 4) {
              if (request.status === 200) {
                  call_success_handler();
              }
              else {
                  call_error_handler();
              }
          }
      };
      
      request.open("GET", url , true);
      request.send(null);
      

      如果readyState 从不为“4”,则不会调用任何处理程序,也不会报告错误。您的成功处理程序永远不会被触发,因此您假设事件触发得太快而您没有注意到。


      现在已经不太常见了,但在某些情况下,浏览器可能会让您认为您有竞争条件。 specification 表示在错误条件下应该发生什么,但并非总是如此。旧的/不符合标准的 XMLHttpRequest 实现在古怪的网络条件下表现不佳。该规范的初始(约 2006 年)版本甚至没有解决网络级错误。

      希望大多数浏览器现在都有符合要求的实现,希望大多数框架应该正确处理错误情况。


      有一个关于异步调试的great article by Pearl Chen 值得一读,如果您想更深入地研究它。

      此外,这里还有关于 ajax 问题的更多信息:jQuery $.ajax, error handler doesn't work

      【讨论】:

        猜你喜欢
        • 2019-12-03
        • 2023-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多