views:

181

answers:

5

Hi everyone,

Very simple question: suppose I have the following js/jquery code

doSomething();

$.get(url, callback);

doSomethingElse();

I understand that right after the GET request is sent doSomethingElse() starts being executed. Now suppose that the server's reply arrives while doSomethingElse() is executing. What happens?

  • Does the callback run in a separate thread in parallel to doSomethingElse()?
  • Does the execution of doSomethingElse() pause until the callback runs and returns?
  • Does the callback only get called once doSomethingElse() has returned?

Thank you for any insight!

lara

A: 

I honestly don't know the answer, but I wouldn't place any code in doSomethingElse() that is dependent on something that callback() does. I know that doSomethingElse() will always run first, but as far as timing/thread issues I'm not sure.

Colin O'Dell
+1  A: 

No, there is only one thread of control for Javascript. The currently executing function will continue running until it completes, then the callback will be invoked once it is ready.

So to specifically answer your question, the callback only gets called once doSomethingElse() has returned. Assuming, of course, that the GET request is successful - if an error occurrs then the callback will never be executed.

Justin Ethier
+4  A: 

No, JavaScript in web browsers is single-threaded, by design. That means that although the ajax call may start immediately (and be processed by another thread in the browser), your callback won't happen until the JavaScript interpreter is next idle. Things to do get queued up waiting for the interpreter to become idle and process them.

Edit Answering your specific questions:

Does the callback run in a separate thread in parallel to doSomethingElse()?

No, the callback will run in the same logical thread as doSomethingElse. (It would be implementation-dependant whether that's the same actual underlying OS thread, but you have no way of knowing and you don't care; logically, it's the same thread.)

Does the execution of doSomethingElse() pause until the callback runs and returns?

By default, the get will be asynchronous, so no. doSomethingElse initiates the request, but then continues. (It's possible to do a synchronous get via the underlying XmlHttpRequest mechanism, but it's a very bad idea -- tends to lock up the UI of the browser completely while the request is running, which is ugly -- and I don't know how you do it with jQuery.)

Does the callback only get called once doSomethingElse() has returned?

With an asynchronous get (the usual kind), you can be certain that doSomethingElse will finish before the callback gets called, yes. This is because the JavaScript interpreter will only do one thing at a time, and it doesn't switch to doing a new thing until it's done with the current one. So although doSomethingElse triggers the get (and the get may be processed by other, non-JavaScript threads in parallel to JavaScript), your callback won't happen until after the interpreter is done with doSomethingElse and anything that called it.

I wouldn't be surprised if at some point we start getting multiple threads in browser-based JavaScript, but if and when we do, it'll have to be explicit, since we all happily assume one thread for the moment.

T.J. Crowder
+2  A: 

To all intents and purposes there are no threads in JS, therefore execution does not happen on a separate thread.

What web APIs do do is make use of asynchronous callbacks, and that's what is happening here -- get() returns immediately, your callback function will be called once the load is complete and there is no other JS code running.

olliej
olliej, but what does it mean that "there is no other JS code running"? Does it mean after the next statement is completed? After the function from which I ran .get() returns? Or until all JS code in my page has been executed?
laramichaels
What he means is that if JavaScript code is running it not be interrupted by other JavaScript code from a callback. So for example if the code is in the middle of executing a a .ready() event, the code in the ready event must finish before your callback will be executed.
Justin Ethier
thank you for clarifying that!
laramichaels
A: 

Here is a pretty good article that illustrates how this works.

http://www.javascriptkata.com/2007/06/12/ajax-javascript-and-threads-the-final-truth/

Chris Gutierrez
thank you for the link, chris. But after reading it I still don't understand what defines *when* the callback gets executed. Is it after the current function returns? When all JS code on the page has been executed? After the current JS statement has been executed...? thanks for any insight
laramichaels
The callback is called when the get request is completed. So, under the hood the $.get() makes an async XMLHttpRequest to the script path you provide. When that request object receives a response from your server it then executes the provided callback.
Chris Gutierrez