เพิ่มฟังก์ชัน Timeout / Sleep ภายใน javascript loop

Nov 24 2020

ฉันพยายามเพิ่มฟังก์ชัน 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

คำตอบ

2 OskarGrosser Nov 25 2020 at 00:10

คุณสามารถใช้async/awaitคุณสมบัติของ ES6 ได้ !

ในการใช้งานawaitจำเป็นต้องอยู่ในฟังก์ชัน / นิพจน์ที่ประกาศasyncไว้

โดยพื้นฐานแล้วสิ่งนี้จะทำให้ฟังก์ชันของคุณเป็นแบบอะซิงโครนัสและรอให้เป็นPromiseไปตามข้อกำหนด setTimeout()เราจะให้สัญญาว่าจะสำเร็จหลังจากที่ล่าช้าชุดใช้
โปรดทราบว่า "after a set delay" ไม่ได้หมายความว่า "หลังจากนั้นทุกประการ" โดยทั่วไปหมายถึง "เร็วที่สุดหลังจาก"

เมื่อทำเช่นนี้ฟังก์ชันอะซิงโครนัสจะรอให้คำสัญญาบรรลุผลโดยปล่อยให้ callstack ว่างในระหว่างนี้เพื่อให้สามารถเรียกใช้โค้ดอื่นได้

ลำดับการดำเนินการของตัวอย่างนี้คือ (แบบง่าย) ดังนี้:

  1. sleepingFunc() วางอยู่บน callstack
    • ในการทำซ้ำ: awaitเพื่อให้คำมั่นสัญญาเป็นจริงการระงับการโทรนี้🡒การปล่อยให้ callstack ว่าง
  2. โทรใหม่บน callstack
  3. ในที่สุดสัญญาก็เป็นจริงสิ้นสุดawait🡒ระงับการโทรกลับใน callstack
  4. ทำซ้ำจนกว่าจะ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();

2 Jkarttunen Nov 24 2020 at 22:48

การดำเนินการนี้จะเรียกใช้ข้อมูลโค้ดจะรันหนึ่งภารกิจทุกๆ 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)