Does a Javascript process have multiple threads of execution?
Background
I am creating an 'addressbook'-type application. There are a lot of entries to load. One idea was to initially load a small subset of the entries, to get the user started, then queue up the remaining entries, giving priority to the entries that the user clicks on. (e.g. if they click on the names that start with X, load those first before processing the rest of the queue). The idea is to load an initial dataset upon initialization (via AJAX) and then load the rest in the background (making a lot of AJAX calls).
My many questions
Conceptually, I know how to do this, but I'm not clear on the limitations of the Javascript engine:
Is order of execution browser dependent? One of the things I tried to do was queue up the set of entries (A's, B's, C's, etc) and then make a whole bunch of requests all at once. This wasn't very successful. I got most of the calls back, but not in any particular order. I need all of my calls back. :)
How do I debug this/track this? I'm not sure how Javascript handles the response; it was easy enough for a single response, but I'm not sure how to handle multiple, relatively large responses from the server.
Is there a single thread of execution for a given page? That is, if the Javascript gets a response from the server but is still executing code, does the transaction block until the currently executing code finishes?
Would it be recommended to put in a delay between requests? This could also cause problems because the loading up and sending of the request (as of now) is in the initialization phase; if I have to sleep() between requests, then I might as well just force the user to wait for the all the data to load without trying to do this gradual loading.
I looked around on SO but I didn't find anything useful. I'm curious about how JS process these asynchronous requests/responses.
What I've done so far
Just to give folks a better idea of what's happening, here's what I'm doing in order of execution. There are 5 hard-coded search categories: first names, last names, classes, regions, states. Each of these categories have ranges. For example the first names category might have 26 ranges, one for each letter of the alphabet: "Aardvark - Azariah" would be an example of a range. Each range has the user information for each user in that range. I have two tables: a ranges table and a users table.
- Initialize range table and range data source objects. Map range table object to specific events.
- AJAX call to get all the ranges for each category. We wait for this before continuing.
- Initialize users table similarly to range table.
- Build a load queue to get all the users for each range. The load queue looks like this: [ lastNames['S'], states['CA'], regions['northwest'], lastNames['A'], etc]
- Preselect a the first names category, the 'A' first names range and the zeroeth user in that range. (This is just an arbitrary choice I made to give the user a starting point)
- AJAX call to get all the users for firstName['A']. Remove the firstNames['A'] range from the load queue.
- Populate the appropriate UI elements
- Loop through our load queue, dequeuing ranges and constructing AJAX requests for the data.
There are a lot of other details too... but this is the basic gist of it.
What happens is that my range table gets populated fine... but then the browser just blocks up (spod) and then my users table gets all sorts of crazy data being populated in it. Clearly the latter is a UI bug on my part so I have to investigate that, but it's not clear to me that this is the best way to do this.
At step 7, I'm not sure if there should be a delay between requests. Ideally, if a user chose a specific range, say states['AK'], we would process that request first, dq'ing that range from our load queue. But if I'm sending开发者_C百科 all the requests on the front end, then we'd never get a chance to give our chosen range the appropriate priority.
Javascript is completely single-threaded.
If you make multiple AJAX calls, you will receive each response as soon as the server sends it; the order depends on the amount of time that it takes the server to send each reply.
If your code is still running when the server replies, the reply will only be processed after your code finishes.
You should try to load all of the data in a single request.
Is order of execution browser dependent? One of the things I tried to do was queue up the set of entries (A's, B's, C's, etc) and then make a whole bunch of requests all at once. This wasn't very successful. I got most of the calls back, but not in any particular order. I need all of my calls back.
The order of execution is not browser dependent. They're event-driven, and the events are up to you. When you say "queue", there's no message queue in the mix; you mean whatever mechanism the server has for taking these in and assigning them to threads.
The return time of the calls is determined by the length of time required to fulfill them. There's a non-deterministic network in-between your browser and the server, so you won't be able to tell.
How do I debug this/track this? I'm not sure how Javascript handles the response; it was easy enough for a single response, but I'm not sure how to handle multiple, relatively large responses from the server.
Google Chrome has some very nice debugging tools, donated by Apple and made open source. Check those out. Or you can try Firefox Firebug.
Is there a single thread of execution for a given page? That is, if the Javascript gets a response from the server but is still executing code, does the transaction block until the currently executing code finishes?
JavaScript is single threaded.
Would it be recommended to put in a delay between requests? This could also cause problems because the loading up and sending of the request (as of now) is in the initialization phase; if I have to sleep() between requests, then I might as well just force the user to wait for the all the data to load without trying to do this gradual loading.
I wouldn't put a delay between requests. I think that defeats the purpose.
I'd recommend looking at jQuery to help with this.
Ajax stands for "Asynchronous JavaScript and XML". "Asynchronous" means that there is no way to know at request-time in which order the responses will arrive.
JavaScript has (at the moment) no mechanism for threading, so you have two possibilities:
- Request the next part after the last one has arrived. This might be very slow and inefficient , because one hanging request will block all others.
- Create a list/array for all possible request and start loading the important ones. If the user wants something else, start loading the rest too. Store the responses at the right position in your array; This will make your script order-independent and you can check if everything is there by simply looping through your array.
JavaScript is an evented programming language, that's why you'll see a lot of this pattern:
someFunction(arguments, callbackFunction () {
// code fired after a process or event is fired
});
I you're not getting all the responses of your requests, there's something wrong with your implementation or the resource that you're querying. You could use Firebug to get a deeper understanding of what's going on.
Are you using any JavaScript framework, they make the use of XHR requests (a.k.a. Ajax) pretty easy. I recommend jQuery.
精彩评论