setTimeout หรือ setInterval


763

เท่าที่ฉันสามารถบอกได้จาวาสคริปต์ทั้งสองชิ้นนี้มีวิธีการทำงานแบบเดียวกัน:

ตัวเลือก A:

function myTimeoutFunction()
{
    doStuff();
    setTimeout(myTimeoutFunction, 1000);
}

myTimeoutFunction();

ตัวเลือก B:

function myTimeoutFunction()
{
    doStuff();
}

myTimeoutFunction();
setInterval(myTimeoutFunction, 1000);

มีความแตกต่างระหว่างการใช้setTimeoutและsetIntervalหรือไม่?


6
หากท่านต้องการรายละเอียดที่ดีบางอย่างเกี่ยวกับวิธีการจับเวลาในการทำงาน JS, จอห์นเรซิกเขียนดีบทความในหัวข้อนี้
ราฟาเอล

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


4
ขอบคุณ @JapanPro แต่ฉันไม่เคยมีปัญหากับการหมดเวลาทำงาน โพสต์นี้เกี่ยวกับความแตกต่างคืออะไรและควรใช้อย่างไร
Damovisa

คำตอบ:


670

โดยพื้นฐานแล้วพวกเขาพยายามทำสิ่งเดียวกัน แต่setIntervalวิธีการนั้นจะมีความแม่นยำมากกว่าsetTimeoutวิธีการนับตั้งแต่setTimeoutรอ 1,000 มิลลิวินาทีทำการเรียกใช้ฟังก์ชันแล้วตั้งค่าการหมดเวลาอีกครั้ง ดังนั้นช่วงเวลารอนั้นจริง ๆ แล้วจะน้อยกว่า 1,000 มิลลิวินาที (หรือมากกว่านั้นถ้าฟังก์ชั่นของคุณใช้เวลาในการประมวลผลนาน)

ถึงแม้คนหนึ่งอาจจะคิดว่าsetIntervalจะดำเนินการตรงทุก 1000ms มันเป็นสิ่งสำคัญที่จะทราบว่าsetIntervalยังจะล่าช้าเนื่องจาก JavaScript ไม่ใช่ภาษาแบบมัลติเธรดซึ่งหมายความว่า - ถ้ามีส่วนอื่น ๆ ของสคริปต์ที่ทำงาน - ช่วงเวลาที่จะมี เพื่อรอให้เสร็จ

ในซอนี้คุณสามารถเห็นได้อย่างชัดเจนว่าการหมดเวลาจะลดลงในขณะที่ช่วงเวลาเกือบตลอดเวลาที่โทร 1 ครั้ง / วินาที (ซึ่งสคริปต์พยายามทำ) หากคุณเปลี่ยนตัวแปรความเร็วที่ด้านบนให้เป็นขนาดเล็กเช่น 20 (หมายถึงมันจะพยายามเรียกใช้ 50 ครั้งต่อวินาที) ช่วงเวลานั้นจะไม่ถึงค่าเฉลี่ย 50 รอบต่อวินาทีเลยทีเดียว

การหน่วงเวลานั้นแทบจะไม่สำคัญ แต่ถ้าคุณกำลังเขียนโปรแกรมบางอย่างที่แม่นยำจริง ๆ คุณควรไปที่ตัวจับเวลาการปรับตัวเอง


4
แอนดี้มีข้อเสนอแนะที่คล้ายกัน สมมุติว่านี่หมายความว่าหากวิธีนั้นใช้เวลามากกว่า 1,000 มิลลิวินาทีในการดำเนินการคุณสามารถมีมากกว่าหนึ่งการทำงานพร้อมกันได้หรือไม่?
Damovisa

14
ในทางทฤษฎีใช่ ในทางปฏิบัติไม่ได้เนื่องจาก Javascript ไม่รองรับมัลติเธรด หากรหัสของคุณใช้เวลานานกว่า 1,000 มิลลิวินาทีมันจะหยุดเบราว์เซอร์
Kamiel Wanrooij

61
เทคนิครหัสเคยชินรันว่าทุก 1000ms เพราะมันขึ้นอยู่กับความละเอียดของตัวตั้งเวลาและไม่ว่ารหัสอื่น ๆ ที่ดำเนินการอยู่แล้ว ประเด็นของคุณยังคงอยู่
Matthew Crumley

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

5
ความแตกต่างคือ setTimeout ไม่ได้ทำซ้ำตัวเอง ช่วยให้คุณสามารถเรียกใช้สคริปต์หลังจากเวลาที่กำหนด แต่เพียงครั้งเดียว setInterval ในทางกลับกันจะทำซ้ำสคริปต์นั้นจนกว่าจะหยุดทำงานด้วย clearTimeout ()
Leander

648

มีความแตกต่างหรือไม่?

ใช่. การหมดเวลาดำเนินการตามระยะเวลาที่กำหนดหลังจากที่เรียกว่า setTimeout () ช่วงเวลาดำเนินการจำนวนหนึ่งของเวลาหลังจากช่วงเวลาก่อนหน้ายิง

คุณจะสังเกตเห็นความแตกต่างหากฟังก์ชั่น doStuff () ของคุณใช้เวลาสักครู่ในการดำเนินการ ตัวอย่างเช่นถ้าเราแสดงการเรียกไปยัง setTimeout / setInterval ด้วย.การยิงของการหมดเวลา / ช่วงเวลาด้วย*และการเรียกใช้โค้ด JavaScript ด้วย[-----]ไทม์ไลน์จะมีลักษณะดังนี้:

Timeout:

.    *  .    *  .    *  .    *  .
     [--]    [--]    [--]    [--]

Interval:

.    *    *    *    *    *    *
     [--] [--] [--] [--] [--] [--]

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

.    *    *        *        *    *
     [-]  [-----][-][-----][-][-]  [-]

•แสดงช่วงเวลาการยิงที่ไม่สามารถเรียกใช้รหัสได้ทันทีและถูกระงับไว้

ดังนั้นช่วงเวลาลอง 'ทัน' เพื่อกลับตามกำหนดเวลา แต่พวกเขาไม่ได้คิวหนึ่งอยู่ด้านบนของกันและกัน: จะมีเพียงหนึ่งการดำเนินการที่ค้างอยู่ต่อช่วงเวลา (หากพวกเขาทั้งหมดเข้าคิวเบราว์เซอร์จะถูกทิ้งไว้พร้อมกับรายการการประหารที่โดดเด่น!)

.    *            x            x
     [------][------][------][------]

x หมายถึงการยิงช่วงเวลาที่ไม่สามารถดำเนินการหรือรอดำเนินการดังนั้นจึงถูกยกเลิก

หากฟังก์ชั่น doStuff () ของคุณใช้เวลาในการดำเนินการนานกว่าช่วงเวลาที่กำหนดไว้เบราว์เซอร์จะกิน CPU 100% ที่พยายามให้บริการและอาจตอบสนองน้อยลง

คุณใช้อันไหนและเพราะอะไร

Chained-Timeout มอบช่วงเวลาว่างที่รับประกันให้กับเบราว์เซอร์ ช่วงพยายามที่จะให้แน่ใจว่าฟังก์ชั่นที่กำลังรันจะทำงานใกล้เคียงที่สุดเท่าที่จะเป็นไปได้ตามกำหนดเวลา

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

ในแง่ของความเข้ากันได้ของเบราว์เซอร์ setTimeout จะมี setInterval แต่เบราว์เซอร์ทั้งหมดที่คุณจะพบในวันนี้จะรองรับทั้งสอง คนสุดท้ายที่หลงทางมานานหลายปีคือ IE Mobile ใน WinMo <6.5 แต่หวังว่าตอนนี้เราจะอยู่ข้างหลังเราเช่นกัน


แต่เหตุผลของการเลือกระหว่างช่วงเวลาและการหมดเวลาถือเป็นจริงแม้แต่แพลตฟอร์มที่ไม่ใช่เบราว์เซอร์เช่นเช่น WebOS หรือ JIL?
Vid L

2
วิธีที่ดีในการทำไทม์เอาท์ของเชนในฟังก์ชั่นนิรนาม: setTimeout (function () {setTimeout (arguments.callee, 10)}, 10)
Justin Meyer

1
ในแง่ของความเข้ากันได้ของเบราว์เซอร์แม้ว่าเบราว์เซอร์ทั้งหมดจะมีทั้งสองวิธี
unigg

"แต่ก็มีโอกาสที่มันจะไม่สนับสนุนสิ่งอื่นที่คุณกำลังใช้" เป็นจริงมาก
พื้นฐาน

1
เครื่องกลองโดยโครงการโครเมียมโดยใช้ setTimeout ("schedule ()", 0); ดังนั้นเบราว์เซอร์จะไม่มีสแต็คที่ไม่จำเป็นเมื่อมันเป็นแท็บพื้นหลังสำหรับโครเมี่ยมหรือขาดทรัพยากร
Elliot Yap

91

setInterval ()

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

setInterval()หากคุณต้องการรหัสห่วงสำหรับภาพเคลื่อนไหวหรือบนนาฬิกาติ๊กใช้แล้ว

function doStuff() {
    alert("run your code here when time interval is reached");
}
var myTimer = setInterval(doStuff, 5000);

setTimeout ()

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

function doStuff() {
    alert("run your code here when time interval is reached");
}
var myTimer = setTimeout(doStuff, 5000);

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


6
คำอธิบายที่ดี แต่โปรดทราบว่า OP เข้าใจถึงความแตกต่างพื้นฐานในตัวอย่างที่ OP ให้ไว้ โดยเฉพาะอย่างยิ่งโปรดสังเกตว่าในsetTimeout()ตัวอย่างของ OP setTimeout()เรียกว่าแบบเรียกซ้ำในขณะที่setInterval()ไม่ใช่
DavidRR

44

setInterval ทำให้ง่ายต่อการยกเลิกการเรียกใช้โค้ดในอนาคต หากคุณใช้ setTimeout คุณต้องติดตาม id ตัวจับเวลาในกรณีที่คุณต้องการยกเลิกในภายหลัง

var timerId = null;
function myTimeoutFunction()
{
    doStuff();
    timerId = setTimeout(myTimeoutFunction, 1000);
}

myTimeoutFunction();

// later on...
clearTimeout(timerId);

กับ

function myTimeoutFunction()
{
    doStuff();
}

myTimeoutFunction();
var timerId = setInterval(myTimeoutFunction, 1000);

// later on...
clearInterval(timerId);

35
ฉันไม่เห็นว่าคุณไม่ได้ติดตาม id ตัวจับเวลาในกรณีของ setInterval อย่างไร มันเพิ่งดึงออกมาจากฟังก์ชั่น
Kekoa

1
อีกทางเลือกหนึ่งsetTimeoutคือแทนที่จะบันทึก id เพิ่มifคำสั่งเพื่อตั้งค่าการหมดเวลาครั้งต่อไปเมื่อเงื่อนไขบางอย่างเป็นจริงเท่านั้น
nnnnnn

7
Kekoa จุดดี แต่คุณต้องบันทึกรหัสช่วงเวลาเพียงครั้งเดียว รหัสการหมดเวลาอาจเปลี่ยนแปลงได้ในทุกการขอร้องดังนั้นคุณต้องติดตามการเปลี่ยนแปลงเหล่านี้ รหัสที่ต้องการล้างการหมดเวลาต้องมีการเข้าถึงค่าปัจจุบันของตัวแปรนี้ นอกจากนี้เป็นไปไม่ได้ที่จะล้างการหมดเวลาในขณะที่ทำงานdoStuffเพราะรหัสไม่ถูกต้อง อย่างไรก็ตามไม่จำเป็นต้องประหยัดรหัสการหมดเวลา แต่คุณสามารถหยุดโทรsetTimeoutได้
Robert

4
จากประสบการณ์ของฉันเวลาส่วนใหญ่ที่คุณต้องการจะสามารถยกเลิกได้แม้ในขณะที่ใช้ setTimeout 99% ของเวลาที่คุณต้องการยกเลิกก่อนที่จะมีการเรียกใช้ครั้งถัดไปไม่ใช่หลังจากที่การร้องขอถัดไปเสร็จสิ้น
Kamiel Wanrooij

23

ฉันพบsetTimeoutวิธีการใช้ง่ายขึ้นถ้าคุณต้องการยกเลิกการหมดเวลา:

function myTimeoutFunction() {
   doStuff();
   if (stillrunning) {
      setTimeout(myTimeoutFunction, 1000);
   }
}

myTimeoutFunction();

นอกจากนี้หากมีบางอย่างผิดพลาดในฟังก์ชั่นมันก็จะหยุดทำซ้ำในข้อผิดพลาดครั้งแรกแทนที่จะทำซ้ำข้อผิดพลาดทุกวินาที


20

ความแตกต่างในจุดประสงค์ของพวกเขาคือ

setInterval()
   -> executes a function, over and over again, at specified time intervals  

setTimeout()
   -> executes a function, once, after waiting a specified number of milliseconds

มันง่ายอย่างที่คิด

รายละเอียดเพิ่มเติมอย่างละเอียดที่นี่http://javascript.info/tutorial/settimeout-setinterval


7
คำอธิบายรวบยอดที่ดี แต่ทราบว่า OP เข้าใจถึงความแตกต่างพื้นฐานในตัวอย่างที่ OP ให้ไว้ โดยเฉพาะอย่างยิ่งโปรดสังเกตว่าในsetTimeout()ตัวอย่างของ OP setTimeout()เรียกว่าแบบเรียกซ้ำในขณะที่setInterval()ไม่ใช่
DavidRR

14

เมื่อคุณเรียกใช้ฟังก์ชั่นบางอย่างภายใน setInterval ซึ่งใช้เวลานานกว่าการหมดเวลา -> เบราว์เซอร์จะติดขัด

- เช่นdoStuff ()ใช้เวลา 1500 วินาที ที่จะดำเนินการและคุณทำ: setInterval (doStuff, 1,000);
1) เบราว์เซอร์รันdoStuff ()ซึ่งใช้เวลา 1.5 วินาที จะถูกประหารชีวิต
2) หลังจาก ~ 1 วินาทีมันจะพยายามรันdoStuff ()อีกครั้ง แต่ก่อนหน้าdoStuff ()ยังคงถูกเรียกใช้งาน -> ดังนั้นเบราว์เซอร์จะเพิ่มการเรียกใช้นี้ในคิว (เพื่อเรียกใช้หลังจากทำครั้งแรก)
3,4, .. ) การเพิ่มคิวในการดำเนินการซ้ำสำหรับการทำซ้ำครั้งถัดไป แต่doStuff ()จากก่อนหน้านี้ยังอยู่ในระหว่างดำเนินการ ...
เนื่องจากผลลัพธ์ - เบราว์เซอร์ค้างอยู่

เพื่อป้องกันไม่ให้ปัญหานี้วิธีที่ดีที่สุดคือการใช้setTimeout setTimeout ภายในที่จะเลียนแบบ setInterval
หากต้องการแก้ไขการหมดเวลาระหว่างการโทร setTimeout คุณสามารถใช้ทางเลือกการแก้ไขด้วยตนเองกับเทคนิคsetInterval ของ JavaScript


1
ฉันไม่รู้ว่าทำไมไม่มีใครพบค่าใด ๆ ในคำตอบนี้!
Randika Vishman

9

ฉันใช้ setTimeout

เห็นได้ชัดว่าความแตกต่างคือ setTimeout เรียกวิธีการหนึ่งครั้ง setInterval เรียกมันซ้ำแล้วซ้ำอีก

นี่เป็นบทความที่ดีที่อธิบายความแตกต่าง: บทช่วยสอน: ตัวจับเวลา JavaScript พร้อม setTimeout และ setInterval


2
ครับผมได้ความแตกต่างที่ แต่ทั้งสองชิ้นของรหัสที่ให้ไว้แล้วควรทำสิ่งเดียวกัน ...
Damovisa

อืมใช่ ... ฉันคงคิด ... แต่จากการเกรงขามและการนับคะแนนของเขานั่นไม่ใช่สิ่งที่เกิดขึ้น
Bravax

9

รหัสของคุณจะมี intevals การดำเนินการที่แตกต่างกันและในบางโครงการเช่นเกมออนไลน์มันไม่เป็นที่ยอมรับ ก่อนอื่นคุณควรทำอย่างไรเพื่อให้โค้ดของคุณทำงานกับ intevals เดียวกันคุณควรเปลี่ยน "myTimeoutFunction" เป็น:

function myTimeoutFunction()
{
    setTimeout(myTimeoutFunction, 1000);
    doStuff();
}
myTimeoutFunction()

หลังจากการเปลี่ยนแปลงนี้จะเท่ากับ

function myTimeoutFunction()
{
    doStuff();
}
myTimeoutFunction();
setInterval(myTimeoutFunction, 1000);

แต่คุณจะยังไม่ได้ผลลัพธ์ที่มั่นคงเนื่องจาก JS เป็นเธรดเดี่ยว ในตอนนี้ถ้าเธรด JS กำลังยุ่งอยู่กับบางสิ่งบางอย่างมันจะไม่สามารถเรียกใช้ฟังก์ชันการเรียกกลับของคุณได้และจะเลื่อนการดำเนินการออกไป 2-3 มิลลิวินาที คุณมี 60 การประมวลผลต่อวินาทีและแต่ละครั้งที่คุณสุ่ม 1-3 วินาทีล่าช้ามันจะไม่เป็นที่ยอมรับอย่างแน่นอน (หลังจากหนึ่งนาทีจะมีความล่าช้าประมาณ 7200 มิลลิวินาที) และฉันสามารถแนะนำให้ใช้สิ่งนี้:

    function Timer(clb, timeout) {
        this.clb = clb;
        this.timeout = timeout;
        this.stopTimeout = null;
        this.precision = -1;
    }

    Timer.prototype.start = function() {
        var me = this;
        var now = new Date();
        if(me.precision === -1) {
            me.precision = now.getTime();
        }
        me.stopTimeout = setTimeout(function(){
            me.start()
        }, me.precision - now.getTime() + me.timeout);
        me.precision += me.timeout;
        me.clb();
    };

    Timer.prototype.stop = function() {
        clearTimeout(this.stopTimeout);
        this.precision = -1;
    };

    function myTimeoutFunction()
    {
        doStuff();
    }

    var timer = new Timer(myTimeoutFunction, 1000);
    timer.start();

รหัสนี้จะรับประกันระยะเวลาการดำเนินการที่มั่นคง แม้เธรดจะไม่ว่างและรหัสของคุณจะถูกเรียกใช้งานหลังจาก 1005 mseconds ในครั้งถัดไปที่จะมีการหมดเวลาสำหรับ 995 msec และผลลัพธ์จะมีเสถียรภาพ


7

ฉันได้ทำการทดสอบอย่างง่าย ๆsetInterval(func, milisec)เพราะฉันสงสัยว่าจะเกิดอะไรขึ้นเมื่อการใช้เวลาของฟังก์ชันมากกว่าช่วงเวลา

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

ฉันได้ทำการทดสอบกับ Chrome v23 แล้ว ฉันหวังว่ามันจะถูกนำไปใช้อย่างไม่แน่นอนในเบราว์เซอร์สมัยใหม่ทั้งหมด

window.setInterval(function(start) {
    console.log('fired: ' + (new Date().getTime() - start));
    wait();
  }, 1000, new Date().getTime());

เอาต์พุตคอนโซล:

fired: 1000    + ~2500 ajax call -.
fired: 3522    <------------------'
fired: 6032
fired: 8540
fired: 11048

waitฟังก์ชั่นเป็นเพียงหัวข้อการปิดกั้นผู้ช่วย - อาแจ็กซ์โทรซิงโครซึ่งจะใช้เวลาตรง2,500 มิลลิวินาทีของการประมวลผลที่ฝั่งเซิร์ฟเวอร์:

function wait() {
    $.ajax({
        url: "...",
        async: false
    });
}

1
"ไม่มีสถานการณ์ที่มีการวนซ้ำแบบขนานที่รัน" - ใช่สิ่งนี้ควรเป็นไปไม่ได้ JavaScript ฝั่งไคลเอ็นต์มีรูปแบบการประมวลผลแบบเธรดเดียวดังนั้นจึงไม่มีสิ่งใด (ตัวจัดการเหตุการณ์ ฯลฯ ) เกิดขึ้นในเวลาเดียวกัน ซึ่งเป็นสาเหตุที่ไม่มีอะไรเกิดขึ้น (และเบราว์เซอร์ไม่ตอบสนอง) ในระหว่างการโทร ajax แบบซิงโครนัส
MrWhite

เบราว์เซอร์ตอบสนองในไม่กี่มิลลิวินาทีระหว่าง "ช่วงเวลา" หรือไม่? เหตุการณ์อื่นจะเริ่มขึ้นหรือไม่หากยังค้างอยู่ (ขอบคุณสำหรับการทดสอบ btw +1)
MrWhite

1
ตาม MDN จะถือว่า " การใช้อันตราย " ถ้าฟังก์ชั่นสามารถดำเนินการได้นานกว่าช่วงเวลา ต้องการการsetTimoutโทรซ้ำ
MrWhite

6

หากต้องการดูแตกต่างกันเล็กน้อย: setInterval มั่นใจว่ามีการเรียกใช้รหัสในทุกช่วงเวลาที่กำหนด (เช่น 1000ms หรือจำนวนที่คุณระบุ) ในขณะที่ setTimeout กำหนดเวลาที่จะรอจนกว่าจะมีการเรียกใช้รหัส และเนื่องจากใช้เวลาเพิ่มเติมเป็นมิลลิวินาทีในการเรียกใช้รหัสจึงเพิ่มขึ้นเป็น 1,000 มิลลิวินาทีดังนั้น setTimeout จึงทำงานอีกครั้งในเวลาที่แน่นอน (มากกว่า 1,000 มิลลิวินาที)

ตัวอย่างเช่นตัวจับเวลา / นับถอยหลังไม่ได้ทำกับ setTimeout พวกเขาจะทำกับ setInterval เพื่อให้แน่ใจว่ามันจะไม่ล่าช้าและรหัสทำงานในช่วงเวลาที่กำหนด


5

ทั้ง setInterval และ setTimeout จะส่งคืน id ตัวจับเวลาที่คุณสามารถใช้เพื่อยกเลิกการดำเนินการนั่นคือก่อนที่การหมดเวลาจะเริ่มขึ้น หากต้องการยกเลิกคุณโทรไปที่ clearInterval หรือ clearTimeout เช่นนี้:

var timeoutId = setTimeout(someFunction, 1000);
clearTimeout(timeoutId);
var intervalId = setInterval(someFunction, 1000),
clearInterval(intervalId);

นอกจากนี้การหมดเวลาจะถูกยกเลิกโดยอัตโนมัติเมื่อคุณออกจากหน้าเว็บหรือปิดหน้าต่างเบราว์เซอร์


4

คุณสามารถตรวจสอบความถูกต้องของคำตอบได้ด้วยตัวเองเมื่อคุณเรียกใช้จาวาสคริปต์ต่อไปนี้หรือตรวจสอบJSFiddleนี้

<div id="timeout"></div>
<div id="interval"></div>

var timeout = 0;
var interval = 0;

function doTimeout(){
    $('#timeout').html(timeout);
    timeout++;
    setTimeout(doTimeout, 1);
}

function doInterval(){
    $('#interval').html(interval);
    interval++;
}

$(function(){
    doTimeout();
    doInterval();
    setInterval(doInterval, 1);
});

3

setTimeout ดีกว่าในสถานการณ์เดียวเพราะฉันเพิ่งได้เรียนรู้ ฉันมักจะใช้ setInterval ซึ่งฉันปล่อยให้ทำงานในพื้นหลังนานกว่าครึ่งชั่วโมง เมื่อฉันเปลี่ยนกลับไปที่แท็บสไลด์โชว์ (ซึ่งใช้รหัส) กำลังเปลี่ยนไปอย่างรวดเร็วมากแทนที่จะเป็นทุก 5 วินาทีที่ควรมี ในความเป็นจริงมันเกิดขึ้นอีกครั้งในขณะที่ฉันทดสอบมันมากขึ้นและไม่ว่าจะเป็นความผิดของเบราว์เซอร์หรือไม่ไม่สำคัญเพราะด้วย setTimeout ที่สถานการณ์เป็นไปไม่ได้อย่างสมบูรณ์


ฟังดูราวกับว่าคุณเรียกว่า setInterval ภายในฟังก์ชั่นที่คุณโทร นั่นเป็นวิธีที่คุณวนลูปด้วย setTimeout แต่ด้วย setInterval คุณจะสร้างลูปใหม่ทั้งหมดในแต่ละครั้งที่มีการเรียกใช้
สตีเฟ่นอาร์


2

เพียงเพิ่มสิ่งที่กล่าวไปแล้ว แต่โค้ดรุ่น setTimeout จะไปถึงที่Maximum call stack sizeซึ่งจะหยุดการทำงาน เนื่องจากไม่มีเคสพื้นฐานสำหรับฟังก์ชั่นวนซ้ำที่จะหยุดดังนั้นคุณจะไม่สามารถเรียกใช้มันซ้ำ ๆ ได้


ฉันไม่คิดว่านี่เป็นเรื่องจริง ดูที่นี่stackoverflow.com/questions/8058612/…
Kevin Wheeler

-1

ความแตกต่างทั่วไประหว่างและ setInterval (นิพจน์ระยะเวลา) คือ

setTimeout () จะดำเนินการแสดงออกเพียงครั้งเดียวและหลังจากนั้นระยะเวลาที่กำหนด

อย่างไรก็ตาม

setInterval () จะดำเนินการแสดงออกใน INFINITE-LOOP หลังจากแต่ละช่วงเวลาที่ระบุ


-5

ฉันคิดSetIntervalและSetTimeoutแตกต่าง SetIntervalดำเนินการบล็อกตามเวลาที่กำหนดในขณะที่SetTimeoutรันบล็อกของรหัสครั้งเดียว

ลองชุดรหัสเหล่านี้หลังจากหมดเวลานับถอยหลังวินาที:

setInterval(function(e){
    alert('Ugbana Kelvin');
}, 2000);

แล้วลอง

setTimeout(function(e){
    alert('Ugbana Kelvin');
}, 2000);

คุณสามารถเห็นความแตกต่างสำหรับตัวคุณเอง


นี่ไม่ได้ตอบคำถาม settimeout () สามารถใช้ซ้ำเพื่อให้ผลลัพธ์เดียวกันกับ setinterval คำถามเกี่ยวกับประสิทธิภาพของตัวเลือกทั้งสองนี้
Tomas Gonzalez
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.