在方法返回之前等待ajax完成

时间:2011-09-25 13:39:36

标签: jquery ajax coffeescript

我知道我可以将调用设置为同步,或者在complete()回调中包装所有内容,但它看起来不够优雅。这就是我所拥有的:

_loadShader: (url) ->   
    (@_loadResource url, false).complete (e) ->
        vert = e.responseText.split '[Vertex shader]'
        frag = vert[1].split '[Fragment shader]'

        vertex: frag[0]
        fragment: frag[1]

_loadResource: (url, async) ->
    url = 'Public/' + url

    $.ajax
        url: url
        dataType: 'text'
        async: async or true
        complete:
            @

_loadShader()返回XHR对象,但我真正想要的是它在complete()被触发之前不会返回 - 即使这意味着锁定浏览器。我对结果的处理很重要,我不想在回调中开始包装我的代码。

编辑:重新加入到这里,正是我所追求的:

_loadShader: (url, e) ->    
    result = @_loadResource url, false
    vert = result.split '[Vertex shader]'
    frag = vert[1].split '[Fragment shader]'

    shader = 
        vertex: frag[0]
        fragment: frag[1]

_loadResource: (url, async = true) ->
    url = 'Public/' + url
    xhr = $.ajax
        url: url
        dataType: 'text'
        async: async
    return xhr.responseText

2 个答案:

答案 0 :(得分:1)

会发生什么

  1. 您使用$.ajax
  2. 致电async: false
  3. 服务器响应,jQuery运行您传递给$.ajax的任何回调
  4. _loadResource函数返回。然后,将complete回调附加到它返回的XHR对象。但是因为所有XHR回调都已经运行,所以没有效果。
  5. 相反,您应该将complete回调作为参数传递给_loadResource,并让它将回调提供给$.ajax。因此呼叫变为

    @_loadResource url, false, (e) -> ...
    

    ,函数定义变为

    _loadResource: (url, async = true, complete = (->)) ->
      $.ajax {url, dataType: 'text', async, complete}
    

答案 1 :(得分:0)

我从来没有找到比将私有变量设置为函数然后将该变量设置为jquery回调中的数据更好的解决方案。

代码看起来像这样:

_loadResource: (url) ->
    resource = null #will cause resource to be private variable of _loadResource, not of callback.
    $.ajax
        url: url
        async: false
        success: (data) ->
            resource = data #setting resource to what jquery got from server.
    resource #returning resource.

汇编为:

_loadResource: function(url) {
  var resource;
  resource = null;
  $.ajax({
    url: url,
    async: false,
    success: function(data) {
      return resource = data;
    }
  });
  return resource;
}