How can I call asynchronous functions in a nested for loop without running out of memory?
I have code like this:
for (var i in data) {
for (var j in data[i]) {
f开发者_StackOverflowor (var k in data[i][j]) {
db.data.insert({i:i, j:j, k:k}, emptyCallback);
}
}
}
but I run out of memory because it's queuing up all the inserts. How can I make the for loop pause until the insert is complete?
I've tried pushing all the records to an array to insert later, but then the array gets too big and again I run out of memory.
you need to iterate to next key each time callback is called, something like this:
function get_first_keys(data, keys)
{
var ki = Object.keys(data);
for (var i = keys[0]; i < ki.length; ++i)
{
var kj = Object.keys(data[ki[i]]);
for (var j = keys[1]; j < kj.length; ++j)
{
var kk = Object.keys(data[ki[i]][kj[j]]);
for (var k = keys[2]; k < kk.length; ++k)
{
return [i, j, k];
}
}
}
}
function get_next_keys(data, keys)
{
var i = keys[0];
var j = keys[1];
var k = keys[2];
var ki = Object.keys(data);
var kj = Object.keys(data[ki[i]]);
var kk = Object.keys(data[ki[i]][kj[j]]);
if (k + 1 < kk.length)
return [i, j, k + 1];
if (j + 1 < kj.length)
return get_first_keys(data, [i, j+1, 0]);
if (i + 1 < ki.length)
return get_first_keys(data, [i+1, 0, 0]);
return;
}
var current_keys = get_first_keys(data, [0, 0, 0]);
function insert()
{
if (!current_keys)
return;
key = {};
key.i = Object.keys(data)[current_keys[0]];
key.j = Object.keys(data[key.i])[current_keys[1]];
key.k = Object.keys(data[key.j])[current_keys[2]];
db.data.insert(key, insert);
current_keys = get_next_keys(data, current_keys);
}
insert();
The simple answer is to do it recursively: do the next insert in the callback rather than passing an empty callback.
精彩评论