开发者

Wait for ajax to complete before method return

开发者 https://www.devze.com 2023-04-07 02:48 出处:网络
I know I can set the call to synchronous, or wrap everything preceeding in the complete() callback, but it seems inelegant. Here\'s what i\'ve got:

I know I can set the call to synchronous, or wrap everything preceeding in the complete() callback, but it seems inelegant. Here's what i've got:

_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() returns the XHR object, but what I really want is for it t开发者_Go百科o not return until complete() gets fired - even if that means locking the browser. What I do with the result is important, and I don't want to start wrapping my code up in callbacks.

edit: re-jigged to this, does precisely what I was after:

_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


What happens is

  1. You call $.ajax with async: false
  2. The server responds, and jQuery runs any callbacks you've passed to $.ajax
  3. The _loadResource function returns. You then attach a complete callback to the XHR object it returned. But because all XHR callbacks were already run, this has no effect.

You should, instead, pass in your complete callback as an argument to _loadResource, and have it provide that callback to $.ajax. So the call becomes

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

and the function definition becomes

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


I never found better solution, than setting private variable to function and then setting that variable to data in jquery callback.

Code would look like this:

_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.

It compiles to:

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

精彩评论

暂无评论...
验证码 换一张
取 消