在发送异步请求时检测变量!= undefined的更好方法

时间:2011-06-01 15:23:37

标签: javascript jquery asynchronous jquery-deferred

鉴于以下内容:

var doThings = (function ($, window, document) { 
  var someScopedVariable = undefined,
      methods,
      _status;

  methods = { 
    init: function () { 
      _status.getStatus.call(this);

      // Do something with the 'someScopedVariable'
    }
  };

  // Local method
  _status = { 
    getStatus: function () { 
      // Runs a webservice call to populate the 'someScopedVariable'

      if (someScopedVariable === undefined) { 
        _status.setStatus.call(this);
      }

      return someScopedVariable;

    },
    setStatus: function () { 
      $.ajax({
           url: "someWebservice",
           success: function(results){
              someScopedVariable = results;
           }
         });
    }
  };

  return methods;

} (jQuery, window, document));

问题很明显,这是一个异步情况,我想等到someScopedVariable未定义,然后继续。

我想过使用jQuery的.when() - > .done()延期电话,但我似乎无法让它工作。我还想过做一个循环,只是检查它是否已定义,但看起来并不优雅。

可能的选项1:

$.when(_status.getStatus.call(this)).done(function () {
        return someScopedVariable; 
});

可能的选项2(可怕的选项):

_status.getStatus.call(this)

var i = 0;
do {
  i++;
} while (formStatusObject !== undefined);

return formStatusObject;

更新 我相信我为了解释它而删除了太多的逻辑,所以我加入了一些。这样做的目的是创建这个数据的访问者。

3 个答案:

答案 0 :(得分:4)

我建议等待ajax调用的完成/成功事件。

  methods = { 
    init: function () { 
      _status.getStatus.call(this);
    },
    continueInit: function( data ) {
      // populate 'someScopedVariable' from data and continue init
    }
  };

  _status = { 
    getStatus: function () { 
      $.post('webservice.url', continueInit );
    }
  };

答案 1 :(得分:1)

您无法阻止使用infite循环等待异步请求完成,因为您的JavaScript最有可能在单个线程中运行。 JavaScript引擎将在尝试调用异步回调之前等待您的脚本完成,该异步回调将更改您在循环中观察的变量。因此,发生了死锁。

唯一的方法是使用回调函数,如第二个选项。

答案 2 :(得分:0)

我同意有关使用回调的其他答案,如果可能的话。如果由于某种原因你需要阻塞并等待响应,请不要使用循环方法,这是最糟糕的方法。最简单的方法是在你的ajax调用中使用set async:false

请参阅http://api.jquery.com/jQuery.ajax/

  

async - Boolean默认值:true默认情况下,   所有请求都是异步发送的   (即默认设置为true)。   如果需要同步请求,请设置   这个选项为false。跨域   requests和dataType:“jsonp”   请求不支持同步   操作。注意同步   请求可以暂时锁定   浏览器,禁用任何操作   请求已激活。