比@yauhen-yakimovich 的answer 更通用:
使用Timeout:
var repeat = (function () {
return function repeat(cbWhileNotTrue, period) {
/// <summary>Continuously repeats callback after a period has passed, until the callback triggers a stop by returning true. Note each repetition only fires after the callback has completed. Identifier returned is an object, prematurely stop like `timer = repeat(...); clearTimeout(timer.t);`</summary>
var timer = {}, fn = function () {
if (true === cbWhileNotTrue()) {
return clearTimeout(timer.t); // no more repeat
}
timer.t = setTimeout(fn, period || 1000);
};
fn(); // engage
return timer; // and expose stopper object
};
})();
使用Interval:
var loop = (function () {
return function loop(cbWhileNotTrue, period) {
/// <summary>Continuously performs a callback once every period, until the callback triggers a stop by returning true. Note that regardless of how long the callback takes, it will be triggered once per period.</summary>
var timer = setInterval(function () {
if (true === cbWhileNotTrue()) clearInterval(timer);
}, period || 1000);
return timer; // expose stopper
};
})();
在 cmets 中表示的两者之间的细微差别 -- repeat 方法仅在回调执行后重复,因此如果您有一个“慢”回调,它不会每 delay 毫秒运行一次,但 重复 在执行之间的每个delay 之后,而loop 方法将每delay 毫秒触发一次回调。为了提前停止,repeat 使用一个对象作为返回的标识符,因此请改用clearTimeout(timer.t)。
用法:
就像@soufiane-hassou 的answer:
var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';
var c = 0;
var interval = repeat/* or loop */(function() {
textScroller.innerHTML += text[c];
c++;
return (c >= text.length);
}, 1000);
如前所述,过早停止是:
/* if repeat */ clearTimeout(interval.t);
/* if loop */ clearInterval(interval);