Javascript/jQuery order of operations
I'm having trouble with a line inside an if statement executing before the conditional is met. What I want to do is:
- Check to see if data (big old array of numbers) is already loaded.
- If not get it and load it into my all_data object.
- Plot data (or in this case alert it)
Here's the code (stripped of many details to be readable
var all_data={};
function get_data(name,rid) {
if (!all_data[name]) {
return $.get('/data.json',
{'name':name},
function(data) {all_data[name]=data;},
开发者_C百科 "json");
} else {return true}
}
function load_file(name,rid) {
if (get_data(name,rid)) { alert(all_data[name]) };
}
What happens with the above code is that when I execute get_data it immediately alerts "undefined" because the jQuery.get is returning a (not yet completed) request object. At this point the entry all_data[name] is undefined. If I wait ~5s the get request completes, and running the code again will just alert "[Object Object]" because the data has loaded. I realize I could just put a function in both the $.get callback and it the else statement but that would make this no longer generalized. Any thoughts?
Chris
Pass the stuff that needs to happen whether or not the data is loaded as a callback function to load_file
itself. This is a general solution since if the data is already available your callback is invoked immediately, otherwise it is invoked when the data becomes available.
Also try to eliminate using the global state all_data
in every function. Limit the scope to local in each function as much as possible.
There are alternate approaches to provide a fluent interface, but without knowing what you're doing with the data after it gets loaded, it is difficult to suggest one.
function load_file(name, rid, fn) {
get_data(name, rid, fn);
}
load_file("..", "..", function() {
alert(all_data[".."]);
});
The get_data
function then becomes:
function get_data(name, rid, fn) {
if (!all_data[name]) {
return $.get('/data.json',
{'name':name},
function(data) { all_data[name]=data; fn(); },
"json");
} else { fn(); }
}
As others have said, the issue is that the $.get() function is asynchronous which immediately returns. You can use the following the make a synchronous request and it will perform the expected operations.
function get_data(name,rid) {
if (!all_data[name]) {
var result = $.ajax({ async: false,
url: '/data.json',
data: {'name':name},
dataType: "json"
});
all_data[name] = result;
return result;
} else {return true}
}
The "async: false" setting will cause the request to be synchronous and will not continue until receiving a response from the url.
精彩评论