วิธีการเปลี่ยนช่วงเวลาแบบไดนามิกในสำหรับวนตามดัชนี / ซ้ำจำนวน?


12

เนื่องจากฉันไม่สามารถแสดงความคิดเห็นได้ฉันถูกบังคับให้เขียนโพสต์นี้ ฉันได้รหัสด้านล่างซึ่งมีความล่าช้า / รออย่างแน่นอน 1 วินาทีหรือ 1,000 มิลลิวินาที -

let n = 5;
for (let i=1; i<n; i++)
{
  setTimeout( function timer()
  {
      console.log("hello world");
  }, i*1000 );
}

แต่ฉันจะหน่วงเวลาฉัน * 1000 วินาทีแทนการแก้ไข 1,000 มิลลิวินาทีดังนั้นการรอขึ้นอยู่กับหมายเลขการวนซ้ำ

ตัวอย่างเช่นถ้า n = 5 ดังนั้นฉันต้องการความล่าช้าของลูป 1 วินาทีในการทำซ้ำครั้งที่ 1 2 วินาทีในการทำซ้ำที่สองและอื่น ๆ .. ความล่าช้าครั้งสุดท้ายจะ 5 วินาที


2
ดังนั้นคุณต้องการที่จะทำให้ 9 ตัวนับ? ถ้าเป็นเช่นนั้นรหัสของคุณจะทำสิ่งที่คุณถาม มันไม่รออย่างแน่นอน 3 วินาที ในความเป็นจริงตัวจับเวลาจะไม่ถูกต้องแน่นอน
Scott Marcus

1
คำถามของคุณไม่สมเหตุสมผล
DanStarns

2
เพิ่งลองใช้รหัสของคุณใน codepen: codepen.io/Connum/pen/BaaBMwWคุณจะได้รับข้อความ 9 ข้อความห่างกัน 3000ms - หากนั่นไม่ใช่สิ่งที่คุณต้องการ (แต่จากคำถามของคุณมันดูเหมือนจะเป็น) โปรดระบุสิ่งที่คุณตั้งใจไว้ คือ.
Constantin Groß

1
คุณดูเหมือนจะไม่เข้าใจว่า setTimeout ทำงานอย่างไรในตอนแรก - ไม่ใช่ "ล่าช้า" ตอนนี้คุณจะได้รับการแจ้งเตือนในช่วงเวลา 3 วินาทีเพราะคุณคูณ 3000 ด้วยi- ถ้าคุณไม่ทำอย่างนั้นคุณจะได้รับการแจ้งเตือนทั้งหมดในเวลาเดียวกัน
04FS

3
การแก้ไขคำถามเพื่อให้ประโยคสุดท้ายของคุณเป็นตัวหนาไม่ได้ช่วยแก้ปัญหาของคุณ ขณะนี้คุณได้รับการบอกเล่าจากผู้แสดงความคิดเห็นหลายคนว่ารหัสของคุณทำสิ่งที่คุณต้องการอยู่แล้ว (หรือค่อนข้างชัดเจนว่าคุณกำลังขออะไรอยู่ถ้าไม่ใช่ผลที่คุณตั้งใจ)
Constantin Groß

คำตอบ:


6

นี่คือฟังก์ชั่นที่จะแสดงทันทีจากนั้น 1 วินาทีในภายหลัง, 2 วินาทีหลังจากนั้น, 3 วินาทีหลังจากนั้นเป็นต้นไปไม่มีคณิตศาสตร์พิเศษไม่จำเป็นต้องสัญญา

const n = 5;
let cnt=0;

function show() {
  console.log("call "+cnt,"delay: ",cnt,"sec");
  cnt++;
  if (cnt > n) return; // we are done
  setTimeout(show, cnt*1000 ); // cnt seconds later
}
show()


1
ฉันขอโทษอย่างยิ่งที่ฉันพลาดคำตอบของคุณมีความคิดเห็นมากมายความเข้าใจผิดคำตอบ ... อย่างไรก็ตามฉันเลือกคำตอบของคุณเนื่องจากคุณเป็นคนแรกที่แก้ไขสิ่งที่ฉันขอขอบคุณสำหรับเวลาของคุณ
Mike

@Mike Lol โซลูชันอื่น ๆ มีประโยชน์ในสิทธิของตนเองดังนั้นขอขอบคุณสำหรับการยอมรับ
mplungjan

Pavan เหมือนกันในไวยากรณ์ ES6 ยากที่จะอ่าน แต่ในความเป็นจริงมันเหมือนกัน การแก้ไขของเขาที่จะทำให้มันถูกสร้างขึ้นในเวลาเดียวกันกับที่ฉันเขียนฉัน :)
mplungjan

8

ในขณะที่งานนี้สามารถแก้ไขได้ด้วยคำสัญญาสตรีมที่ตอบโต้และเครื่องมือที่ยอดเยี่ยมอื่น ๆ (เฮ้ไม่มีใครแนะนำให้ใช้แรงงาน!) แต่ก็สามารถแก้ไขได้ด้วยการคิดเลขเล็กน้อย

ดังนั้นคุณต้องการหมดเวลาในลำดับ: 1 วินาที, หนึ่งก่อนหน้านี้ +2s ก่อนหน้านี้หนึ่ง + 3s ก่อนหน้านี้และอื่น ๆ ลำดับนี้คือ: 1, 3, 6, 10, 15 ... a[n] = n * (n + 1) / 2และสูตรของมันคือ รู้ว่า...

let n = 6;
console.log(new Date().getSeconds());

for (let i = 1; i < n; i++) {
  setTimeout(function timer() {
    console.log(new Date().getSeconds());
  }, 1000 * i * (i + 1) / 2);
}


นักคณิตศาสตร์ยังมีชีวิตอยู่ !! :)
Bilal Siddiqui

5

คุณสามารถลองใช้ async / await (Promises) เพื่อทำให้เป็นอันดับรหัสของคุณ:

const waitSeconds = seconds => new Promise(resolve => setTimeout(resolve, seconds))

async function main () {
 let oldDate = new Date()
 let newDate
 
 /* 
  * If you put 'await' inside the loop you can synchronize the async code, and simulate
  * a sleep function
  */
 for (let i=1; i<5; i++) {
    await waitSeconds(i*1000)
    newDate = new Date()   
    console.log(`Loop for i=${i}, elapsed=${moment(newDate).diff(oldDate, 'seconds')} seconds`)
    oldDate = newDate
 }
 
 console.log('End')
}

main()
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>


5

เอาฉันไปถอดรหัสคำถามของคุณ xD แต่นี่คือสิ่งที่คุณต้องการ?

สิ่งนี้จะทำให้คอนโซลการถ่ายทำบันทึกด้วย i * 1000 ดีเลย์ทุกครั้ง ดังนั้นครั้งแรกที่มันจะมีความยาว 1 วินาที (1 * 1,000) ถัดไปจะเป็น 2 วินาทีเป็นต้น

let i = 0;
loop = () => {
  setTimeout(() => {
    console.log(new Date()); // for clarity
    i++;
    if (i < 10) {
      loop();
    }
  }, i * 1000)
};
loop();


ตัวอย่างเช่นถ้า n = 5 ดังนั้นฉันต้องการความล่าช้าของลูป 1 วินาทีในการทำซ้ำครั้งที่ 1 2 วินาทีในการทำซ้ำที่สองและอื่น ๆ .. ความล่าช้าครั้งสุดท้ายจะ 5 วินาที
Mike

yup สิ่งนี้จะล่าช้า 1 วินาทีสำหรับการทำซ้ำครั้งที่ 1, 2 วินาทีสำหรับที่ 2 และอื่น ๆ ลอง
Pavan Skipo

คำอธิบายของคุณไม่ตรงกับรหัส แต่มันทำงานได้ดี
mplungjan

3

การวนซ้ำไม่รอให้ฟังก์ชันการหมดเวลาใช้งานเสร็จสมบูรณ์ ดังนั้นเมื่อลูปรันมันจะกำหนดเวลาการแจ้งเตือนของคุณสำหรับแต่ละดัชนี

คุณสามารถใช้ฟังก์ชั่นที่จะทำงานตามดัชนีของคุณ แต่กำหนดไว้ในเวลาเดียวกัน คุณสามารถรู้สึกถึงความแตกต่างของ 3 วินาที

function test(i){
    setTimeout( function timer(){
        console.log("hello world" + i);
    }, i*3000);
}
for (let i=1; i<4; i++) {
   test(i);
}

3

ใช้การโทรซ้ำเพื่อแทนการวนซ้ำ

let i=1;
function a(i) {
  if (i > 5)
    return
  else
    b("message", i)
}

function b(s, f) {
  setTimeout(function timer() {
    console.log(s + " " + f + " seconds");
  }, f * 1000);
  a(++i);
}
a(i);


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