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
- You call
$.ajax
withasync: false
- The server responds, and jQuery runs any callbacks you've passed to
$.ajax
- The
_loadResource
function returns. You then attach acomplete
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;
}
精彩评论