I have the following recursive function:
function explore(v, componentN) {
return function () {
nodes[v].visited = true;
nodes[v].componentNumber = componentN;
preVisit(v);
adjList[v].forEach((item) => {
if (!nodes[item].visited){
ex(item, componentN)
}
});
postVisit(v);
return nodes;
}
}
function ex(item, com){
trampoline(function () {
return explore(item, com)
})
}
function trampoline(fn) {
while(fn && typeof fn === 'function') {
fn = fn()
}
}
I want to use setImmediate()
in order to avoid stack overflow issues (it should be implemented in this way and not in the iterative approach). However, when I execute this function I get array res
only with the first one element, while I get it full of all elements if I don't use setImmediate()
and the same situation appears when I use nextTick()
(I know in advance how many elements should be there). What am I doing wrong and how can I implement this function (or analog) properly here?
This is explore()
function before applying trampoline
function explore(v, componentN) {
nodes[v].visited = true;
nodes[v].componentNumber = componentN;
preVisit(v);
adjList[v].forEach((item) => {
if (!nodes[item].visited){
explore(item, componentN)
}
});
postVisit(v);
return nodes;
}
It accepts two arguments: v
is an index in nodes
array which element is supposed to be explored and componentN
which is just a counter of components in a graph. explore()
does not return anything, it just changes the state of an object in the array nodes
under the v
key from unexplored to explored. The main problem is that two functions preVisit(v)
and postVisit(v)
also change the state of that object - write order on which it was visited for the first time and the second time (when popping up stack from the previous calls) respectively. When I converted explore()
with trampoline, they began to write unexpected and wrong results.
The function is being called in another function in this way:
for (let i = 0; i < vNum; i++) {
if (nodes[i].visited) continue;
explore(i, cN);
cN++;
}
And two function postVisit
and preVisit
function preVisit(v){
nodes[v].preVisit = visitCounter;
visitCounter++;
}
function postVisit(v) {
nodes[v].postVisit = visitCounter;
visitCounter++;
}