does the callback passed to jquery's $.get() e

2020-07-27 05:27发布

问题:

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

回答1:

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.



回答2:

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.



回答3:

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.



回答4:

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/



回答5:

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.