Làm cách nào để thay đổi thời gian giữa các khoảng thời gian một cách linh hoạt theo vòng lặp theo chỉ số / số lần lặp?


12

Vì tôi không thể bình luận, tôi buộc phải viết bài này. Tôi đã nhận được mã dưới đây để trì hoãn / chờ chính xác 1 giây hoặc 1000 mili giây -

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

Nhưng làm thế nào tôi có thể trì hoãn nó i * 1000 giây thay vì 1000 mili giây cố định để việc chờ đợi phụ thuộc vào số lần lặp?

Ví dụ: nếu n = 5, thì tôi muốn độ trễ của vòng lặp 1 giây trong lần lặp thứ 1. 2 giây trong lần lặp thứ hai, và cứ thế .. độ trễ cuối cùng sẽ là 5 giây.


2
Vì vậy, bạn muốn thực hiện 9 giờ? Nếu vậy, mã của bạn sẽ làm những gì bạn đang yêu cầu. Nó không đợi chính xác 3 giây. Trong thực tế, bộ tính giờ sẽ không bao giờ chính xác.
Scott Marcus

1
câu hỏi của bạn không có ý nghĩa
DanStarns

2
Chỉ cần thử mã của bạn trong một codepen: codepen.io/Connum/pen/BaaBMwW Bạn nhận được 9 tin nhắn cách nhau 3000ms - nếu đó không phải là điều bạn muốn (nhưng từ câu hỏi của bạn nghe có vẻ như vậy), vui lòng chỉ định kết quả dự định của bạn Là.
Constantin Groß

1
Bạn dường như không hiểu làm thế nào setTimeout hoạt động ở nơi đầu tiên - đó không phải là một sự chậm trễ của YouTube. Ngay bây giờ, bạn sẽ nhận được thông báo của mình sau 3 giây, bạn đã nhân 3000 số với i- nếu bạn không làm điều đó, thì bạn sẽ nhận được tất cả các cảnh báo đó cùng một lúc.
04FS

3
Chỉnh sửa câu hỏi để làm cho câu cuối cùng của bạn in đậm không thực sự giúp ích cho trường hợp của bạn. Bây giờ bạn đã được nhiều người bình luận nói rằng mã của bạn đã thực hiện những gì bạn yêu cầu (hoặc đúng hơn, nó không hoàn toàn rõ ràng những gì bạn THỰC SỰ yêu cầu, nếu đó không phải là kết quả dự định của bạn).
Constantin Groß

Câu trả lời:


6

Đây là một chức năng sẽ hiển thị ngay lập tức, sau đó 1 giây sau, 2 giây sau hơn, 3 giây sau đó, v.v. Không có toán học đặc biệt, không cần lời hứa

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
Tôi vô cùng xin lỗi vì tôi đã bỏ lỡ câu trả lời của bạn, có rất nhiều bình luận, hiểu lầm, câu trả lời ... dù sao tôi cũng đang chọn câu trả lời của bạn vì bạn là người đầu tiên giải quyết những gì tôi hỏi cảm ơn vì thời gian của bạn.
Mike

@Mike Lol. Các giải pháp khác hữu ích theo cách riêng của họ, vì vậy cảm ơn bạn đã chấp nhận
mplungjan

Pavan là giống nhau trong cú pháp ES6. Khó đọc hơn nhưng thực tế là như vậy. Bản chỉnh sửa của anh ấy để làm cho nó được thực hiện cùng lúc với tôi đã viết của tôi :)
mplungjan

8

Mặc dù nhiệm vụ này có thể được giải quyết bằng các lời hứa, các luồng phản ứng và các công cụ tuyệt vời khác (hey, chưa có ai đề xuất sử dụng công nhân!), Nó cũng có thể được giải quyết bằng một ít mỹ phẩm.

Vì vậy, bạn muốn thời gian chờ theo thứ tự: 1s, trước đó + 2s, trước đó + 3s, v.v. Trình tự này là: 1, 3, 6, 10, 15 ... và công thức của nó là a[n] = n * (n + 1) / 2. Biết rằng...

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);
}


Các nhà toán học vẫn còn sống !! :)
Bilal Siddiqui

5

Bạn có thể thử sử dụng async / await (Promise), để tuần tự hóa mã của bạn:

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

Mất một thời gian để giải mã câu hỏi của bạn xD, nhưng đây có phải là điều bạn muốn không?

Điều này sẽ tiếp tục bắn console.log với độ trễ i * 1000 mỗi lần. vì vậy lần đầu tiên nó sẽ dài 1 giây (1 * 1000), tiếp theo sẽ là 2 giây và cứ thế.

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


Ví dụ: nếu n = 5, thì tôi muốn độ trễ của vòng lặp 1 giây trong lần lặp thứ 1. 2 giây trong lần lặp thứ hai, và cứ thế .. độ trễ cuối cùng sẽ là 5 giây.
Mike

yup điều này sẽ trì hoãn 1 giây cho lần lặp đầu tiên, 2 giây cho lần thứ 2 và cứ thế, hãy thử nó
Pavan Skipo

Mô tả của bạn không phù hợp với mã. Nhưng nó thực hiện công việc
mplungjan

3

Vòng lặp không chờ chức năng hết thời gian hoàn thành. Vì vậy, khi vòng lặp chạy, nó lập lịch cảnh báo cho từng chỉ mục.

Bạn có thể sử dụng một chức năng sẽ chạy theo chỉ mục của bạn nhưng được lên lịch cùng một lúc. Bạn có thể cảm thấy sự khác biệt của 3 giây.

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

3

Sử dụng các cuộc gọi đệ quy thay vì vòng lặp

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);


Ví dụ: nếu n = 5, thì tôi muốn độ trễ của vòng lặp 1 giây trong lần lặp thứ 1. 2 giây trong lần lặp thứ hai, và cứ thế .. độ trễ cuối cùng sẽ là 5 giây.
Mike
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.