Need help with pop-ing from a stack

Hi,

Through a asynchronous request a fill up a stack (2-dimentional) but now I can’t ‘pop’ something off. It keeps giving a ‘undefined’;

The stack looks like this:


var stack = new Array();

function fillstack(){
stack[startStop + '_' + hash] = new Array;
stack[startStop + '_' + hash]['set'] = '';
stack[startStop + '_' + hash]['hash'] = '';
stack[startStop + '_' + hash]['latlng'] = '';
stack[startStop + '_' + hash]['startStop'] = '';

// offcourse there is more logic to fill those fields, but a console.log reveals a full stack
// when it's done, it calls the popfromstack()
}

In a other function I want check if somthing is in the stack, and if so pop something of and then process it (they are start and stop adresses and need to be geocoded, so I need to space out the request to prevent floading)


function popfromstack() {
	console.log(stack);

        dataitem = stack.pop();
	console.log(dataitem);

	if (dataitem['set'] == 'empty'){
		$('#' + dataitem['startStop'] + '_' + dataitem['hash']).html('no data');
	}
...

The console.log(stack) returns the filled stack. but dataitem keeps being undefined. What am I doing wrong?

The pop method is only effective with numerically indexed arrays.

What could work is to define an object with your info, and to push that object on to your stack.


stack.push({
    key: startStop + '_' + hash,
    set: '',
    hash: '',
    latlng: '',
    startStop: ''
});

Yeay! That works. Now I’m on to the next problem.

The stack gets filled with data coming from a getJSON (jquery) (assynchonously)
The problem is that the process I want to do with them needs to be spaced out in time. So I want to pop off one element every second or so.

I was thinking I could do this with something like while(stack.size() > 0) { }
but there is offcourse the odd change the stack is still empty the first time this is done.

Is there a way to use SetInterval and have it stop when everything is actually done?

There is. You set a reference to the timed interval, so that at the end of things you can clear that interval.

Something like the following might do the trick.


stack.timer = setInterval(function () {
    var item = stack.pop();
    if (!item) {
        clearInterval(stack.timer);
    }
    ...
}, 1000); // 1000 milliseconds is one second

Hi Paul,

Thx, I’ve implemented something like this. I only have a few weird cases in which it is possible all my items are proccessed (so the interval is cleared), but if the processing of one fails they get pushed back on the stack for a retry. Because the processing happens asynchronizely it is possible that a item gets pushed to the stack for a retry while the ‘last’ item is already done and the timer is cleared.

Is there a way to check if the timer is running/active and if not, restart it?

The code has this structure:


var stack = new Array();

elements.each(i, e) {

// build stack
if (i == (num_elements-1)){
		startpopping();
	}
}

function startpopping(){
	timer = setInterval("popfromstack()", 1300);
}

function popfromstack() {

	dataitem = stack.pop();

	if(typeof(dataitem) == "undefined"){
		console.log('undefined data-object. Excecution ended succesfully');
		

		// If all elements are 'no data', the pop form stack is called, but no elements exist
		// check if this is the last element
		if (num_elements == 0) {
			clearInterval(timer);
		}
		
		return;
	}

// Processs

}

Yes there is. When the clearInterval command is issued, you can assign that back to stack.timer whereupon it will be undefined.

That way when you push a value to the stack, you can check if (!stack.timer) and assign the setInterval from there.

Ah, you mean like:


timer = clearInterval(timer);

and then later on


if(!timer) {
startpopping();
}

where startpopping wil restart te timer and recall popfromstack()

It’s not a good idea to use global variables in that way though, which is why placing the timer on the array that it’s accessing is a good way to prevent future potential issues.