我正在尝试遍历订单列表,暂停每个订单3秒钟。然后一旦完成,再循环一次。
在下面的代码段中,如果循环启用,它似乎在第一个循环完成之前再次启动循环。
每次调用display_notification之间的3秒暂停也不起作用。
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);
}
答案 0 :(得分:1)
一旦完成设置超时功能的循环,您就会调用this.start()
。
跟踪index
的最后一个值并使用它来设置start()
调用的超时时间,或者将调用设置为start()
在您设置的最后一个超时功能中循环。
答案 1 :(得分:1)
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.