Reputation: 2225
I am trying to iterate through a list of orders, pausing each one for 3 seconds. Then once complete, start again in a loop.
In the snippet below, if the loop is enabled it seems to be starting the loop again before the first loop has completed.
Also the 3 second pause between each call to display_notification is not working.
start: function() {
$.each(this.orders, function(index, order) {
setTimeout(function() {
console.log ('show notification');
recentlyApp.display_notification(order);
}, index * 3000);
});
if (this.settings.loop) {
this.start();
}
},
display_notification: function(order) {
console.log(order);
}
Upvotes: 1
Views: 87
Reputation: 11733
As soon as you're already using jQuery, you can create a plugin to loop through an array in an interval.
Example:
// timer function that loops through an array with in a given interval
$.timer = function (list, callback, time/*, onFinish, index*/) {
var onFinish = arguments.length > 3 ? arguments[3] : void 0,
index = arguments.length > 4 ? arguments[4] : 0;
if (index < list.length) {
list.__timed = setTimeout(function() {
callback.call(this, index, list[index]);
$.timer(list, callback, time, onFinish, ++index);
}, time);
}
else if (onFinish){
onFinish.call(this);
}
return {
cancel: function() {
if (list.__timed !== void 0) {
clearTimeout(list.__timed);
delete list.__timed;
}
}
};
}
// usage
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var timer = $.timer(arr, function (index, item) {
document.querySelector('div').insertAdjacentHTML('beforeend', '<div>' + item + '</div>');
}, 3000, function() {
document.querySelector('div').insertAdjacentHTML('beforeend', '<div>Finished</div>');
});
// cancelling the loop
$('button').click(function(e) {
timer.cancel();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>
<button>Cancel timer</button>
So, in your scenario, it would be something like this:
start: function() {
$.timer(this.orders, function(index, order) {
console.log('show notification');
recentlyApp.display_notification(order);
}, 3000, this.settings.loop ? this.start : void 0);
},
display_notification: function(order) {
console.log(order);
}
UPDATE
Now, the $.timer
is returning an object with the cancel
method, so you can cancel the loop at anytime by calling .cancel();
.
I've created a __timed
property into the array to always get the last setTimeout
executed, so when you call the cancel
method, it calls the clearTimeout
for what it was going to call next.
Upvotes: 1
Reputation: 944545
You're calling this.start()
as soon as you've finished the loop that sets up the timeout functions.
Either track the last value of index
and use it to set a timeout on the call to start()
or put the call to start()
in the last timed out function you set going in the loop.
Upvotes: 1