【问题标题】:javascript Race condition issuejavascript竞争条件问题
【发布时间】:2012-02-03 16:15:11
【问题描述】:

我有两个函数,一个函数是重新加载函数,它执行 ajax Web 调用来获取数据。另一个是加载数据的项目加载器。问题是加载数据项的函数由于 ajax 调用还没有值。除了调用 setTimeout 之外,还有什么办法解决这个问题?提前感谢您的帮助。

function reload(index) {
    _ListData[index] = null;
    DisplayInformation.GetTemplateTableInformation(
        ListManager.listReportId(),
        ListManager.listParameters(),
        ListManager.listSortParams(),
        TableReportHelper_TemplateRelatedAction,
        reloadRange.min, 
        reloadRange.num,
        function(templateItemIfo) {//success callback causes issues with race conditon in the function itemLookaheadCallback because _ListData[index] = null;
            itemLookaheadCallback(templateItemIfo, index);
        });
}

这是尝试加载在重新加载回调中调用的项目的函数

 function loadDataCallback(lookAheadData, index, loadNeighbors) {
    //Store the received value
    var item = _ListData[index];//this will be null because of _ListData[index] = null;
    item.data = lookAheadData.TemplateInformation;

};

【问题讨论】:

  • 你能把你的代码简化为问题的关键吗?
  • +1 以上。缺少上下文。用更通用的方式描述这个问题。
  • 对不起,我把代码减少了一点 var item = _ListData[index];将为空,这就是问题所在。函数重新加载回调 itemLookaheadCallback 设置索引项的速度不够快。
  • 我认为不可能在这个问题的上下文中回答,因为我们不知道这些函数的作用。但是,作为一般规则,您不应该有一个依赖于 xmlHttpRequest 响应的函数,该响应不是通过该请求的 onreadystatechange 侦听器以某种方式调用的。如果您遵循该规则,您将不会有竞争条件。
  • 说有race condition 是不正确的,因为JavaScript 是单线程的; JavaScript 程序中不能存在竞争条件。

标签: javascript ajax callback race-condition


【解决方案1】:

将加载项目的代码放在“成功回调”中。

或者,使 AJAX 调用同步,但应避免这种情况,因为在连接速度较慢或数据量很大时,您的页面可能看起来像已冻结。

【讨论】:

    【解决方案2】:

    我知道这看起来像一个竞争条件,但我会冒险并建议它实际上是一个范围问题。

    _ListData 存在于 reload() 函数内部,如果我没记错的话,回调可能会继承该范围并仍使其可访问一层。

    function reload(index) {
        _ListData[index] = null;
        ...
    }
    

    但是回调的回调(看起来您可能正在这样做)可能会失去该范围并存在于完全匿名的范围中。

    reload -> itemLookaheadCallback -> loadDataCallback
    

    解决方案?考虑使用window 为该变量定义一个全局可访问的位置。 (window 始终是全局的)。

    以下是实现这一目标的更改:

    function reload(index) {
        window._ListData[index] = null;
        ...
    }
    
    function loadDataCallback(lookAheadData, index, loadNeighbors) {
        var item = window._ListData[index];
        ...
    };
    

    无论如何,这只是一个猜测。可能是错误的,但相对容易验证。

    【讨论】:

      【解决方案3】:

      您可以在 ajax 调用中使用 async=False 进行同步调用。例如:

      $.ajax({
                  type: 'GET',
                  url: '/yourUrl/',
                   dataType: 'json',
                  success: function(data) {
      
                  },
                  data: {},
                  async: false
              });
      

      p.s.:这里使用jQuery进行Ajax调用。

      【讨论】:

      • @josh3736 为什么?永远不要在没有解释的情况下做出如此有力的明确声明!
      • 点击链接。同步调用会冻结浏览器 UI,这是令人尴尬的糟糕 UX。
      猜你喜欢
      • 2013-12-31
      • 1970-01-01
      • 2023-01-30
      • 1970-01-01
      • 1970-01-01
      • 2010-11-27
      • 2010-09-25
      • 2023-03-23
      • 1970-01-01
      相关资源
      最近更新 更多