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 to 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
$.ajaxwithasync: false$.ajax_loadResourcefunction returns. You then attach acompletecallback to the XHR object it returned. But because all XHR callbacks were already run, this has no effect.You should, instead, pass in your
completecallback as an argument to_loadResource, and have it provide that callback to$.ajax. So the call becomesand the function definition becomes