Here's the deal:
I populate a local array in a callback like so:
var datasource = datasources[id];
var contexts = [];
datasource.data($selected.parent().data(), function (items) {
var dataarr = items.data;
for (var i = 0; i < dataarr.length; ++i) {
contexts.push(dataarr[i]);
}
});
foo(contexts);
Now, in foo, I run a simple check like:
function foo(contexts) {
if (contexts.length < 2) {
return;
}
}
If I break at the return statement above, contexts.length is in fact, greater than 2. Similarly, if I run the code step by step in a debugger, everything works as expected.
This make me suspect that when not running in a debugger, this code is being executed before the callback has completed.
Fine. But how can I control the execution order? Or, perhaps, is there a better paradigm to go about this if the only way I know can acquire items.data
is from within that callback?
Thanks!
I'm not sure about the context here a little bit, but if you want your method foo
to be called after the array has been populated, why not call it after the for loop? like so:
datasource.data($selected.parent().data(), function (items) {
var dataarr = items.data;
for (var i = 0; i < dataarr.length; ++i) {
contexts.push(dataarr[i]);
}
foo(contexts);
});
if you're uncomfortable with that, look at PubSubJS which allows you to emit events and handle them asynchronously. I wrote an article about it's usage here.
Edit: An example:
datasource.data($selected.parent().data(), function (items) {
var dataarr = items.data;
for (var i = 0; i < dataarr.length; ++i) {
contexts.push(dataarr[i]);
}
PubSub.publish('contextsPopulated', contexts);
});
and then modify foo
as:
function foo(message, contexts) {
if (contexts.length < 2) {
return;
}
}
now register foo to be called whenever 'contextsPopulated'
is signalled.
PubSub.subscribe('contextsPopulated', foo);