0

when i run my code i get the following, it happens too fast and seems like its just fires instead of waiting for async callbacks.

4/4: Adding events for week 9 [###################] 12/12
1/4: Adding events for week 6 [###################] 20/20
2/4: Adding events for week 7 [###################] 32/32
3/4: Adding events for week 8 [###################] 40/40

or if i print every line out instead of updating the line

4/4: Adding events for week 9 [##########         ] 6/12
2/4: Adding events for week 7 [##                 ] 1/32
2/4: Adding events for week 7 [###                ] 2/32
2/4: Adding events for week 7 [#####              ] 3/32
1/4: Adding events for week 6 [###                ] 1/20
1/4: Adding events for week 6 [#####              ] 2/20
2/4: Adding events for week 7 [######             ] 4/32
2/4: Adding events for week 7 [########           ] 5/32
2/4: Adding events for week 7 [#########          ] 6/32
3/4: Adding events for week 8 [#                  ] 1/40
3/4: Adding events for week 8 [###                ] 2/40
3/4: Adding events for week 8 [####               ] 3/40
4/4: Adding events for week 9 [############       ] 7/12
4/4: Adding events for week 9 [#############      ] 8/12
4/4: Adding events for week 9 [#################  ] 9/12

it should not happen, it should first add all events for week 6, then 7 and so on.

I want the run the next function in the queue when the event is added (async), based on this https://stackoverflow.com/a/3584027/3774580 queue manager (changed it a bit.)

var Queue = function(){
    this.queue = [];
    this.index = 0;
    this.cb = function(){};
};

Queue.prototype = {
    add: function(fn){
        this.queue.push({
            fn: fn
        });
    },
    run: function(index){
        (index || index === 0) && (this.index = index);
        this.next();
    },
    next: function(){
        var self = this,
            i = this.index++,
            at = this.queue[i],
            next = this.queue[this.index];

        if(at){ 
            at.fn();
        }
        if(next){
            self.next();
        }else if(this.index == this.queue.length){
            this.cb.call(this);
        }
    },
    reset: function(){
        this.index = 0;
    },
    onEnd: function(callback){
        this.cb = callback;
    }
};

it all worked fine with timeouts while testing, then i replaced timeout with queue to minimize wasted time waiting for next iteration. so this worked:

var timeout = 0;
weeks.forEach(function(week, index){
    setTimeout(function() {
        webuntis.fetchWeek(week, class_id, function(event){ /* ... */ });
    }, timeout );
    timeout += 3000;
});

here is where i use it, have tried adding the 500ms timeout just as a test

var WeekQueue = new Queue();
weeks.forEach(function (week, index) { //weeks = array with Date objects
    WeekQueue.add(function () {
        webuntis.fetchWeek(week, result.class_id, function (events) { //asyc callback
            var EventQueue = new Queue(), 
                bar = new ProgressBar((index + 1) + '/' + weeks.length + ': Adding events for week ' + week.getWeek(1) + ' [:bar] :current/:total', {/* config removed */});

            for (var e in events) {
                EventQueue.add(function () {
                    var event = events[e]; /* rest of vars removed */
                    icloud.addEvent(cal_ref, event.uid, start, end, description, event.zone[0], event.title[0], function (err, res) { //async callback
                        if (!err) {
                            bar.tick();
                            setTimeout(function () {
                                EventQueue.next()
                            }, 500);
                        }
                    });
                });
            }
            EventQueue.onEnd(function () {
                setTimeout(function () {
                    WeekQueue.next()
                }, 500);
            });
            EventQueue.run();
        });// /webuntis.fetchWeek
    });// /WeekQueue.add
});// /weeks.forEach
WeekQueue.run();

what am i doing wrong?

Community
  • 1
  • 1
keja
  • 1,333
  • 1
  • 14
  • 21
  • You should use a library to control the async flow instead of playing with timeouts. Async is very good at that and there is a queue helper too: https://github.com/caolan/async#queue – Shanoor Feb 14 '16 at 16:05
  • Thank, i will give that a try – keja Feb 14 '16 at 16:09

1 Answers1

0

thanks to @ShanShan it works, ended up using https://github.com/caolan/async#queue instead of the other queue manager

keja
  • 1,333
  • 1
  • 14
  • 21