เพิ่มฟังก์ชัน Timeout / Sleep ภายใน javascript loop
ฉันพยายามเพิ่มฟังก์ชัน sleep / delay ภายในไฟล์ js อันนี้:
var webTest = function()
{
let regex = /^https?:\/\//;
let url = $('#list_urls').val().split('\n');
var xmlhttp = [], i;
var myObj2 = [], i;
for(let i = 0; i < url.length; i++)
{
(function(i) {
xmlhttp[i] = new XMLHttpRequest();
url[i] = url[i].replace(regex, '');
xmlhttp[i].open("GET", "https://website.com/API?key=<MY_API_KEY>&url="+url[i], false);
xmlhttp[i].onreadystatechange = function() {
if (xmlhttp[i].readyState === 4 && xmlhttp[i].status === 200) {
myObj2 = JSON.parse(xmlhttp[i].responseText);
document.getElementById("demo"+i).innerHTML = myObj2.results[1].categories;
}
};
xmlhttp[i].send();
})(i);
console.log(`The Server2: `+ myObj2);
}
}
ฉันต้องการให้สคริปต์นี้หยุดชั่วคราวเป็นเวลา 10 วินาทีแล้วทำงานอีกครั้งจากนั้นหยุดอีกครั้งเป็นเวลา 10 วินาทีและทำเหมือนกับว่าความยาวของข้อความนี้จะมากกว่าที่ฉันวนซ้ำ! รหัสของฉันใช้งานได้ถ้าฉันทำงานเป็นครั้งเดียว แต่จะไม่ทำงานหากฉันทำงานในวงเนื่องจากเว็บไซต์มีการ จำกัด อัตราในapiดังนั้นฉันจึงพยายามเพิ่มฟังก์ชันการนอนหลับ
ดังนั้นสิ่งที่ฉันพยายามคือรอการนอนหลับ (); วิธีการและยังลองใช้วิธีsetTimeoutแต่มันไม่ทำงานตามที่คาดไว้ในการจัดเรียงมันใช้ไม่ได้กับรหัสของฉันเลย!
รอการนอนหลับ (); ไม่ทำงานเลยและแสดงข้อความเช่นUncaught SyntaxError: await ใช้ได้เฉพาะในฟังก์ชัน async และตัวสร้าง async webTestfile.js: 27
คำตอบ
คุณสามารถใช้async/awaitคุณสมบัติของ ES6 ได้ !
ในการใช้งานawaitจำเป็นต้องอยู่ในฟังก์ชัน / นิพจน์ที่ประกาศasyncไว้
โดยพื้นฐานแล้วสิ่งนี้จะทำให้ฟังก์ชันของคุณเป็นแบบอะซิงโครนัสและรอให้เป็นPromiseไปตามข้อกำหนด setTimeout()เราจะให้สัญญาว่าจะสำเร็จหลังจากที่ล่าช้าชุดใช้
โปรดทราบว่า "after a set delay" ไม่ได้หมายความว่า "หลังจากนั้นทุกประการ" โดยทั่วไปหมายถึง "เร็วที่สุดหลังจาก"
เมื่อทำเช่นนี้ฟังก์ชันอะซิงโครนัสจะรอให้คำสัญญาบรรลุผลโดยปล่อยให้ callstack ว่างในระหว่างนี้เพื่อให้สามารถเรียกใช้โค้ดอื่นได้
ลำดับการดำเนินการของตัวอย่างนี้คือ (แบบง่าย) ดังนี้:
sleepingFunc()วางอยู่บน callstack- ในการทำซ้ำ:
awaitเพื่อให้คำมั่นสัญญาเป็นจริงการระงับการโทรนี้🡒การปล่อยให้ callstack ว่าง
- ในการทำซ้ำ:
- โทรใหม่บน callstack
- ในที่สุดสัญญาก็เป็นจริงสิ้นสุด
await🡒ระงับการโทรกลับใน callstack - ทำซ้ำจนกว่าจะ
sleepingFunc()เสร็จ
ดังที่คุณเห็นในขั้นตอนที่ 3 หากการโทรอื่นใช้เวลานานกว่าความล่าช้าการโทรที่ถูกระงับจะต้องรอนานกว่านั้น
function sleep(ms) {
return new Promise(resolveFunc => setTimeout(resolveFunc, ms));
}
async function sleepingFunc() {
for (let i = 0; i < 5; ++i) {
console.log(i + " - from sleep");
await sleep(1000);
}
}
function synchronousFunc() {
for (let i = 0; i < 5; ++i) {
console.log(i + " - from sync");
}
}
sleepingFunc();
synchronousFunc();
การดำเนินการนี้จะเรียกใช้ข้อมูลโค้ดจะรันหนึ่งภารกิจทุกๆ 1 วินาทีจนกว่าเงื่อนไขจะเป็นที่พอใจจากนั้นจึงล้างตัวจับเวลา
const work = (i)=>{
console.log('doing work here ', i);
}
let counter = 0
const timer = setInterval(()=>{
if (timer && ++counter >= 10) {
clearInterval(timer)
}
work(counter);
}, 1000)