มันมีวิธีการกำหนดค่าsetInterval
วิธีการจาวาสคริปต์เพื่อดำเนินการวิธีการทันทีแล้วดำเนินการกับตัวจับเวลา
มันมีวิธีการกำหนดค่าsetInterval
วิธีการจาวาสคริปต์เพื่อดำเนินการวิธีการทันทีแล้วดำเนินการกับตัวจับเวลา
คำตอบ:
มันง่ายที่สุดที่จะเรียกใช้ฟังก์ชั่นของคุณโดยตรงในครั้งแรก:
foo();
setInterval(foo, delay);
อย่างไรก็ตามมีเหตุผลที่ดีที่ควรหลีกเลี่ยงsetInterval
- โดยเฉพาะในบางกรณีเหตุการณ์ทั้งหมดsetInterval
สามารถมาถึงกันได้ทันทีโดยไม่ล่าช้า อีกเหตุผลหนึ่งคือถ้าคุณต้องการหยุดลูปคุณต้องโทรอย่างชัดเจนclearInterval
ซึ่งหมายความว่าคุณต้องจำหมายเลขอ้างอิงที่ส่งคืนจากการsetInterval
โทรเดิม
ดังนั้นวิธีทางเลือกคือให้foo
ทริกเกอร์ตัวเองสำหรับการโทรครั้งต่อไปที่ใช้setTimeout
แทน:
function foo() {
// do stuff
// ...
// and schedule a repeat
setTimeout(foo, delay);
}
// start the cycle
foo();
สิ่งนี้รับประกันว่ามีอย่างน้อยช่วงเวลาdelay
ระหว่างการโทร นอกจากนี้ยังทำให้การยกเลิกการวนซ้ำง่ายขึ้นถ้าจำเป็นคุณไม่ต้องโทรsetTimeout
เมื่อถึงเงื่อนไขการยกเลิกการวนซ้ำ
ยังดีกว่าคุณสามารถสรุปได้ทั้งหมดในนิพจน์ฟังก์ชันที่ถูกเรียกใช้ทันทีซึ่งสร้างฟังก์ชันซึ่งจะเรียกตัวเองอีกครั้งตามข้างบนและเริ่มลูปโดยอัตโนมัติ:
(function foo() {
...
setTimeout(foo, delay);
})();
ซึ่งกำหนดฟังก์ชั่นและเริ่มรอบทั้งหมดในครั้งเดียว
setTimeout
?
setInterval
สามารถมาถึงกันได้ทันทีโดยไม่ล่าช้า
setTimeout
วิธีนี้?
ฉันไม่แน่ใจว่าฉันเข้าใจคุณถูกต้องหรือไม่ แต่คุณสามารถทำสิ่งนี้ได้อย่างง่ายดาย:
setInterval(function hello() {
console.log('world');
return hello;
}(), 5000);
เห็นได้ชัดว่ามีหลายวิธีในการทำเช่นนี้ แต่นั่นเป็นวิธีที่กระชับที่สุดที่ฉันสามารถนึกได้
arguments.callee
ไม่สามารถใช้ได้ในโหมดเข้มงวด ES5
ฉันสะดุดกับคำถามนี้เนื่องจากปัญหาเดียวกัน แต่ไม่มีคำตอบช่วยถ้าคุณจำเป็นต้องทำตัวเหมือนsetInterval()
แต่มีความแตกต่างเพียงอย่างเดียวที่ฟังก์ชั่นถูกเรียกทันทีที่เริ่มต้น
นี่คือวิธีแก้ไขปัญหานี้ของฉัน:
function setIntervalImmediately(func, interval) {
func();
return setInterval(func, interval);
}
ข้อดีของการแก้ปัญหานี้:
setInterval
สามารถปรับเปลี่ยนได้ง่ายโดยการทดแทนclearInterval()
ต่อไปในภายหลังตัวอย่าง:
// create 1 second interval with immediate execution
var myInterval = setIntervalImmediately( _ => {
console.log('hello');
}, 1000);
// clear interval after 4.5 seconds
setTimeout( _ => {
clearInterval(myInterval);
}, 4500);
หากต้องการหน้าด้านหากคุณต้องการใช้จริงๆsetInterval
คุณสามารถเปลี่ยนต้นฉบับsetInterval
ได้ ดังนั้นจึงไม่จำเป็นต้องเปลี่ยนรหัสเมื่อเพิ่มข้อมูลนี้ก่อนรหัสที่มีอยู่ของคุณ:
var setIntervalOrig = setInterval;
setInterval = function(func, interval) {
func();
return setIntervalOrig(func, interval);
}
ยังคงข้อดีทั้งหมดตามที่ระบุข้างต้นใช้ที่นี่ แต่ไม่จำเป็นต้องทดแทน
setTimeout
วิธีแก้ปัญหาเพราะมันจะคืนค่าsetInterval
วัตถุ เพื่อหลีกเลี่ยงการเรียกฟังก์ชั่นซึ่งอาจเป็นรหัสในภายหลังและไม่ได้กำหนดไว้ในเวลาปัจจุบันฉันจะตัดการเรียกฟังก์ชันแรกในsetTimeout
ฟังก์ชันดังนี้: setTimeout(function(){ func();},0);
ฟังก์ชันแรกจะถูกเรียกหลังจากรอบการประมวลผลในปัจจุบันซึ่งเป็นทันทีเช่นกัน ข้อผิดพลาดเพิ่มเติมได้รับการพิสูจน์
คุณสามารถสรุปsetInterval()
ฟังก์ชั่นที่แสดงพฤติกรรมดังกล่าวได้:
function instantGratification( fn, delay ) {
fn();
setInterval( fn, delay );
}
... จากนั้นใช้แบบนี้:
instantGratification( function() {
console.log( 'invoked' );
}, 3000);
นี่คือเสื้อคลุมที่จะสวยถ้าคุณต้องการ:
(function() {
var originalSetInterval = window.setInterval;
window.setInterval = function(fn, delay, runImmediately) {
if(runImmediately) fn();
return originalSetInterval(fn, delay);
};
})();
ตั้งค่าอาร์กิวเมนต์ที่สามของ setInterval เป็นจริงและมันจะทำงานเป็นครั้งแรกทันทีหลังจากเรียก setInterval:
setInterval(function() { console.log("hello world"); }, 5000, true);
หรือละเว้นอาร์กิวเมนต์ที่สามและจะรักษาลักษณะการทำงานดั้งเดิมไว้:
setInterval(function() { console.log("hello world"); }, 5000);
เบราว์เซอร์บางตัวสนับสนุนอาร์กิวเมนต์เพิ่มเติมสำหรับ setInterval ซึ่ง wrapper นี้ไม่ได้คำนึงถึง ฉันคิดว่ามันไม่ค่อยใช้ แต่จำไว้ว่าถ้าคุณต้องการมัน
สำหรับใครบางคนจำเป็นต้องนำด้านนอกthis
เข้ามาราวกับว่ามันเป็นฟังก์ชั่นลูกศร
(function f() {
this.emit("...");
setTimeout(f.bind(this), 1000);
}).bind(this)();
หากการผลิตขยะข้างต้นรบกวนคุณคุณสามารถทำการปิดแทนได้
(that => {
(function f() {
that.emit("...");
setTimeout(f, 1000);
})();
})(this);
ฉันจะแนะนำการเรียกใช้ฟังก์ชันตามลำดับต่อไปนี้
var _timer = setInterval(foo, delay, params);
foo(params)
นอกจากนี้คุณยังสามารถส่งผ่าน_timer
ไปยัง foo ถ้าคุณต้องการclearInterval(_timer)
ในสภาพที่แน่นอน
var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
นี่เป็นเวอร์ชั่นง่าย ๆ สำหรับมือใหม่โดยไม่ต้องวุ่นวาย มันเพิ่งประกาศฟังก์ชั่นเรียกมันแล้วเริ่มช่วงเวลา แค่นั้นแหละ.
//Declare your function here
function My_Function(){
console.log("foo");
}
//Call the function first
My_Function();
//Set the interval
var interval = window.setInterval( My_Function, 500 );
เพื่อแก้ไขปัญหานี้ฉันเรียกใช้ฟังก์ชั่นเป็นครั้งแรกหลังจากโหลดหน้าเว็บแล้ว
function foo(){ ... }
window.onload = function() {
foo();
};
window.setInterval(function()
{
foo();
}, 5000);
มีแพกเกจ npm สะดวกเรียกว่าfirstInterval (การเปิดเผยแบบเต็มมันเป็นของฉัน)
ตัวอย่างจำนวนมากที่นี่ไม่รวมการจัดการพารามิเตอร์และการเปลี่ยนพฤติกรรมเริ่มต้นของsetInterval
โครงการขนาดใหญ่ใด ๆ ถือเป็นความชั่วร้าย จากเอกสาร:
รูปแบบนี้
setInterval(callback, 1000, p1, p2);
callback(p1, p2);
เหมือนกันกับ
firstInterval(callback, 1000, p1, p2);
หากคุณเป็นโรงเรียนเก่าในเบราว์เซอร์และไม่ต้องการการพึ่งพามันเป็นเรื่องง่ายที่ตัดและวางจากโค้ด
// YCombinator
function anonymous(fnc) {
return function() {
fnc.apply(fnc, arguments);
return fnc;
}
}
// Invoking the first time:
setInterval(anonymous(function() {
console.log("bar");
})(), 4000);
// Not invoking the first time:
setInterval(anonymous(function() {
console.log("foo");
}), 4000);
// Or simple:
setInterval(function() {
console.log("baz");
}, 4000);
ตกลงนี่ซับซ้อนมากดังนั้นขอผมเขียนมันง่ายขึ้น:
function hello(status ) {
console.log('world', ++status.count);
return status;
}
setInterval(hello, 5 * 1000, hello({ count: 0 }));
คุณสามารถตั้งค่าเวลาหน่วงเริ่มต้นที่น้อยมาก (เช่น 100) และตั้งเป็นเวลาหน่วงที่คุณต้องการภายในฟังก์ชัน:
var delay = 100;
function foo() {
console.log("Change initial delay-time to what you want.");
delay = 12000;
setTimeout(foo, delay);
}
มีปัญหากับการเรียกใช้ฟังก์ชันของคุณแบบอะซิงโครนัสทันทีเนื่องจาก setTimeout / setInterval มาตรฐานมีการหมดเวลาน้อยที่สุดเกี่ยวกับมิลลิวินาทีหลายวินาทีแม้ว่าคุณจะตั้งค่าเป็น 0 โดยตรงมันเกิดจากงานเฉพาะของเบราว์เซอร์
ตัวอย่างของโค้ดที่มีการหน่วงเวลาเป็นศูนย์จริงซึ่งทำงานใน Chrome, Safari, Opera
function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}
คุณสามารถค้นหาข้อมูลเพิ่มเติมได้ที่นี่
และหลังจากการโทรด้วยตนเองครั้งแรกคุณสามารถสร้างช่วงเวลาด้วยฟังก์ชั่นของคุณ
อันที่จริงเร็วที่สุดคือการทำ
interval = setInterval(myFunction(),45000)
สิ่งนี้จะเรียกว่าฟังก์ชั่นของฉันและจากนั้นจะทำแบบนี้ทุก ๆ 45 วินาทีซึ่งแตกต่างจากการทำ
interval = setInterval(myfunction, 45000)
ซึ่งจะไม่เรียกใช้ แต่กำหนดเวลาเท่านั้น
myFunction()
กลับมาเอง แทนที่จะแก้ไขแต่ละฟังก์ชั่นที่จะเรียกใช้โดยsetInterval
มันเป็นวิธีที่ดีกว่าในการห่อsetInterval
เมื่อคำตอบอื่น ๆ กำลังเสนอ
function
ครั้งเดียวแล้วทำsetInterval()