1

鉴于以下情况:

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;

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

4

3 回答 3

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 );
    }
  };
于 2011-06-01T15:31:00.737 回答
1

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

唯一的方法是在整个过程中使用回调函数,就像您的第二个选项一样。

于 2011-06-01T15:34:08.787 回答
0

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

http://api.jquery.com/jQuery.ajax/

async - Boolean 默认值:true 默认情况下,所有请求都是异步发送的(即默认设置为 true)。如果您需要同步请求,请将此选项设置为 false。跨域请求和 dataType: "jsonp" 请求不支持同步操作。请注意,同步请求可能会暂时锁定浏览器,从而在请求处于活动状态时禁用任何操作。

于 2011-06-01T15:34:57.127 回答