SitePoint Sponsor

User Tag List

Results 1 to 8 of 8
  1. #1
    SitePoint Zealot Hieronymus's Avatar
    Join Date
    Nov 2004
    Location
    Nederland, Eindhoven
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    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:
    Code:
    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)

    Code:
    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?
    What good are one-liners if they don't
    fit.

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,716
    Mentioned
    103 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Hieronymus View Post
    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.

    Code javascript:
    stack.push({
        key: startStop + '_' + hash,
        set: '',
        hash: '',
        latlng: '',
        startStop: ''
    });
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    SitePoint Zealot Hieronymus's Avatar
    Join Date
    Nov 2004
    Location
    Nederland, Eindhoven
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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?
    What good are one-liners if they don't
    fit.

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,716
    Mentioned
    103 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Hieronymus View Post
    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.

    Code javascript:
    stack.timer = setInterval(function () {
        var item = stack.pop();
        if (!item) {
            clearInterval(stack.timer);
        }
        ...
    }, 1000); // 1000 milliseconds is one second
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  5. #5
    SitePoint Zealot Hieronymus's Avatar
    Join Date
    Nov 2004
    Location
    Nederland, Eindhoven
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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:
    Code:
    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
    
    }
    What good are one-liners if they don't
    fit.

  6. #6
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,716
    Mentioned
    103 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Hieronymus View Post
    Is there a way to check if the timer is running/active and if not, restart it?
    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.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  7. #7
    SitePoint Zealot Hieronymus's Avatar
    Join Date
    Nov 2004
    Location
    Nederland, Eindhoven
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ah, you mean like:

    Code:
    timer = clearInterval(timer);
    and then later on
    Code:
    if(!timer) {
    startpopping();
    }
    where startpopping wil restart te timer and recall popfromstack()
    What good are one-liners if they don't
    fit.

  8. #8
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,716
    Mentioned
    103 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Hieronymus View Post
    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.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •