มีวิธีใดในการเรียกใช้ฟังก์ชันเป็นระยะ ๆ ใน JavaScript หรือไม่?


คำตอบ:


215

คุณต้องการsetInterval():

var intervalID = setInterval(function(){alert("Interval reached");}, 5000);

พารามิเตอร์แรกของsetInterval ()ยังสามารถเป็นสตริงของโค้ดที่จะประเมินได้

คุณสามารถล้างฟังก์ชันตามคาบได้ด้วย:

clearInterval(intervalID);

15
ฉันโหวตแล้วตัดสินใจที่จะยกเลิกการโหวตเพิ่ม (แต่ไม่ใช่การลงคะแนน) เพราะคุณใช้อาร์กิวเมนต์สตริงเพื่อ setInterval ควรใช้ฟังก์ชั่นเพื่อสนับสนุนสตริงอาร์กิวเมนต์เพื่อประสิทธิภาพความปลอดภัยและสำหรับคุณสมบัติการปิด
Jason S

5
ไม่เป็นไรฉันไม่รังเกียจ setInterval()เป็นคำตอบที่ถูกต้องสำหรับคำถามไม่ว่าจะเป็นพารามิเตอร์ก็ตาม เป็นเพียงตัวอย่างและทั้งสองวิธีเป็นไปตามคำจำกัดความที่ถูกต้อง
zombat

2
ฉันเห็นด้วยกับ Jason S; มันควรจะเป็นฟังก์ชันจริงๆ ในตัวอย่างของคุณปัญหาเดียวคือการสูญเสียประสิทธิภาพเล็กน้อย แต่เป็นนิสัยที่ไม่ดีในการทำความเข้าใจ
Matthew Crumley

4
ฉันเห็นด้วยกับคุณทั้งคู่การใช้ฟังก์ชันจะดีกว่า ฉันไม่เคยบอกว่ามันไม่ใช่ มันถูกต้องทั้งสองวิธี แต่เพื่อประโยชน์ของความคิดเห็นฉันจะแก้ไขคำตอบให้มีฟังก์ชันแทน
zombat

37

โปรดทราบว่า setInterval () มักไม่ใช่ทางออกที่ดีที่สุดสำหรับการดำเนินการตามระยะเวลา - จริงๆแล้วขึ้นอยู่กับสิ่ง JavaScript คุณจริงเรียกร้องเป็นระยะ ๆ

เช่น. หากคุณใช้ setInterval () ด้วยช่วงเวลา 1000ms และในฟังก์ชัน periodic คุณทำการโทรแบบ ajax ซึ่งบางครั้งจะใช้เวลา 2 วินาทีในการส่งคืนคุณจะทำการโทร ajax อีกครั้งก่อนที่คำตอบแรกจะกลับมา สิ่งนี้มักไม่เป็นที่พึงปรารถนา

ห้องสมุดหลายแห่งมีวิธีการเป็นระยะที่ป้องกันข้อผิดพลาดของการใช้ setInterval อย่างไร้เดียงสาเช่นตัวอย่าง Prototype ที่เนลสันให้ไว้

เพื่อให้ได้การดำเนินการตามระยะที่มีประสิทธิภาพมากขึ้นด้วยฟังก์ชันที่มีการเรียกใช้ jQuery ajax ให้พิจารณาสิ่งนี้:

function myPeriodicMethod() {
  $.ajax({
    url: ..., 
    success: function(data) {
      ...
    },
    complete: function() {
      // schedule the next request *only* when the current one is complete:
      setTimeout(myPeriodicMethod, 1000);
    }
  });
}

// schedule the first invocation:
setTimeout(myPeriodicMethod, 1000);

อีกวิธีหนึ่งคือการใช้ setTimeout แต่ติดตามเวลาที่ผ่านไปในตัวแปรจากนั้นตั้งค่าการหน่วงเวลาการหมดเวลาในแต่ละการเรียกใช้แบบไดนามิกเพื่อเรียกใช้ฟังก์ชันให้ใกล้เคียงกับช่วงเวลาที่ต้องการมากที่สุด แต่จะไม่เร็วกว่าที่คุณจะได้รับคำตอบกลับมา


setTimeout (myPeriodicMethod, 1000); ถูกเรียก 2 ครั้ง จำเป็นไหม ฉันคิดว่าเวลาที่กำหนดควรเรียกเฉพาะในฟังก์ชันที่สมบูรณ์เท่านั้น
Vishnudev K

1
ใช่ setTimeout () ที่สองไม่ใช่ข้อกำหนดคุณสามารถเรียก myPeriodicMethod () ซึ่งจะทำการโทร ajax ครั้งแรกทันที ... แต่ถ้าคุณต้องการกำหนดเวลาด้วยความล่าช้าจากการโทรครั้งแรกคุณสามารถเขียนเป็น ฉันได้เขียน
Matt Coubrough

16

ทุกคนมีโซลูชัน setTimeout / setInterval อยู่แล้ว ฉันคิดว่าสิ่งสำคัญคือต้องสังเกตว่าคุณสามารถส่งผ่านฟังก์ชันไปยัง setInterval ไม่ใช่แค่สตริง ที่จริงแล้วมันอาจจะ "ปลอดภัยกว่า" เล็กน้อยในการส่งผ่านฟังก์ชันจริงแทนที่จะเป็นสตริงที่จะถูก "พัฒนา" ไปยังฟังก์ชันเหล่านั้น

// example 1
function test() {
  alert('called');
}
var interval = setInterval(test, 10000);

หรือ:

// example 2
var counter = 0;
var interval = setInterval(function() { alert("#"+counter++); }, 5000);

3
+1 หากคุณเป็นนักเรียนของโรงเรียน JavaScript ของ Crockfordคุณจะหลีกเลี่ยงการประเมินผลในรูปแบบที่ชั่วร้ายทั้งหมด
Patrick McElhaney

@Patrick - ฉันไม่คิดว่าคำแนะนำ "ห้ามใช้ $ (เครื่องหมายดอลลาร์) หรือ \ (แบ็กสแลช) ในชื่อจะเข้ากันได้ดีกับ jQuery lot :)
Russ Cam

6

คำถามเดิม แต่ .. ฉันยังต้องวิ่งงานวารสารและเขียนTaskTimer นอกจากนี้ยังมีประโยชน์เมื่อคุณต้องทำงานหลายอย่างในช่วงเวลาที่ต่างกัน

// Timer with 1000ms (1 second) base interval resolution.
var timer = new TaskTimer(1000)

// Add task(s) based on tick intervals.
timer.addTask({
    name: 'job1',       // unique name of the task
    tickInterval: 5,    // run every 5 ticks (5 x interval = 5000 ms)
    totalRuns: 10,      // run 10 times only. (set to 0 for unlimited times)
    callback: function (task) {
        // code to be executed on each run
        console.log(task.name + ' task has run ' + task.currentRuns + ' times.');
    }
});

// Start the timer
timer.start();

TaskTimerทำงานได้ทั้งในเบราว์เซอร์และโหนด ดูเอกสารสำหรับคุณสมบัติทั้งหมด






1

วิธีดั้งเดิมคือsetInterval()/ clearInterval()แต่ถ้าคุณใช้ไลบรารีPrototypeอยู่แล้วคุณสามารถใช้ประโยชน์จาก PeriodicalExecutor:

new PeriodicalUpdator(myEvent, seconds);

ซึ่งจะป้องกันการโทรซ้ำซ้อน จากhttp://www.prototypejs.org/api/periodicalExecuter :

"มันป้องกันคุณจากการดำเนินการฟังก์ชันเรียกกลับแบบขนานหลาย ๆ ครั้งหากใช้เวลาดำเนินการนานกว่าช่วงเวลาที่กำหนด (มันยังคงแฟล็ก" กำลังทำงาน "ไว้ภายในซึ่งได้รับการป้องกันจากข้อยกเว้นในฟังก์ชันเรียกกลับ) สิ่งนี้มีประโยชน์อย่างยิ่งหากคุณ ใช้เพื่อโต้ตอบกับผู้ใช้ในช่วงเวลาที่กำหนด (เช่นใช้การแจ้งเตือนหรือยืนยันการโทร): สิ่งนี้จะหลีกเลี่ยงกล่องข้อความหลายกล่องที่รอให้ดำเนินการ "

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.