ฉันจะเพิ่มความล่าช้าในการวนซ้ำ JavaScript ได้อย่างไร


346

ฉันต้องการที่จะเพิ่มความล่าช้า / การนอนหลับภายในwhileวง:

ฉันลองแบบนี้:

alert('hi');

for(var start = 1; start < 10; start++) {
  setTimeout(function () {
    alert('hello');
  }, 3000);
}

เฉพาะสถานการณ์แรกเท่านั้นที่เป็นจริง: หลังจากแสดงalert('hi')แล้วจะรอ 3 วินาทีจากนั้นalert('hello')จะปรากฏขึ้น แต่alert('hello')จะซ้ำ ๆ กันตลอดเวลา

สิ่งที่ฉันต้องการคือหลังจากนั้นalert('hello')จะปรากฏขึ้น 3 วินาทีหลังจากalert('hi')นั้นต้องรอเป็นเวลา 3 วินาทีเป็นครั้งที่สองalert('hello')เป็นต้น

คำตอบ:


750

setTimeout()ฟังก์ชั่นไม่ปิดกั้นและจะกลับทันที ดังนั้นการวนซ้ำของคุณจะวนซ้ำอย่างรวดเร็วและจะเริ่มต้นการหมดเวลา 3 วินาทีจะทริกเกอร์ทีละตัวอย่างรวดเร็ว นั่นคือเหตุผลที่การแจ้งเตือนครั้งแรกของคุณปรากฏขึ้นหลังจาก 3 วินาทีและส่วนที่เหลือทั้งหมดจะติดตามอย่างต่อเนื่องโดยไม่ล่าช้า

คุณอาจต้องการใช้สิ่งนี้แทน:

var i = 1;                  //  set your counter to 1

function myLoop() {         //  create a loop function
  setTimeout(function() {   //  call a 3s setTimeout when the loop is called
    console.log('hello');   //  your code here
    i++;                    //  increment the counter
    if (i < 10) {           //  if the counter < 10, call the loop function
      myLoop();             //  ..  again which will trigger another 
    }                       //  ..  setTimeout()
  }, 3000)
}

myLoop();                   //  start the loop

คุณสามารถทำให้มันเรียบร้อยขึ้นโดยใช้ฟังก์ชั่นการเรียกตนเองผ่านจำนวนการวนซ้ำเป็นอาร์กิวเมนต์:

(function myLoop(i) {
  setTimeout(function() {
    console.log('hello'); //  your code here                
    if (--i) myLoop(i);   //  decrement i and call myLoop again if i > 0
  }, 3000)
})(10);                   //  pass the number of iterations as an argument


27
จะไม่ใช้การเรียกซ้ำเพื่อดำเนินการนี้โดยขึ้นอยู่กับการล้นสแต็กในที่สุดหรือไม่ หากคุณต้องการที่จะทำซ้ำหนึ่งล้านสิ่งที่จะเป็นวิธีที่ดีกว่าในการดำเนินการนี้ อาจจะตั้งค่าช่วงและล้างมันเหมือนโซลูชันของ Abel ด้านล่าง?
Adam

7
@ อดัม: ความเข้าใจของฉันคือว่าเนื่องจาก setTimeout ไม่มีการปิดกั้นนี่ไม่ใช่การรวมซ้ำ - stackwindow จะปิดหลังจากแต่ละ setTimeout และมีเพียง setTimeout เดียวที่รอดำเนินการ ... ใช่มั้ย
โจ

3
มันจะทำงานอย่างไรเมื่อวนวัตถุเช่นfor inวนซ้ำ?
vsync

1
@vsync ตรวจสอบObject.keys()
Braden ที่ดีที่สุด

1
@joey คุณมีความสับสนกับsetTimeout setIntervalการหมดเวลาจะถูกทำลายโดยปริยายเมื่อมีการโทรกลับ
cdhowie

72

ลองสิ่งนี้:

var i = 0, howManyTimes = 10;
function f() {
    alert( "hi" );
    i++;
    if( i < howManyTimes ){
        setTimeout( f, 3000 );
    }
}
f();

69

หากใช้ ES6 คุณสามารถใช้letเพื่อให้บรรลุสิ่งนี้:

for (let i=1; i<10; i++) {
    setTimeout( function timer(){
        alert("hello world");
    }, i*3000 );
}

อะไรletคือการประกาศiสำหรับการวนซ้ำแต่ละรอบไม่ใช่การวนซ้ำ ด้วยวิธีนี้สิ่งที่ผ่านไปsetTimeoutคือสิ่งที่เราต้องการ


1
ขอบคุณ! คงไม่ได้คิดถึงวิธีนี้ด้วยตัวเอง การกำหนดขอบเขตบล็อกจริง ลองจินตนาการว่า ...
โซเฟียโกลด์

1
ฉันเชื่อว่านี่มีปัญหาการจัดสรรหน่วยความจำแบบเดียวกันกับคำตอบที่อธิบายไว้ในstackoverflow.com/a/3583795/1337392
Flame_Phoenix

1
@Flame_Phoenix การจัดสรรหน่วยความจำมีปัญหาอะไร
4castle

1
การเรียกใช้ setTimeout คำนวณค่าของi*3000อาร์กิวเมนต์ในลูปและส่งผ่านไปsetTimeoutตามค่า การใช้letเป็นทางเลือกและไม่เกี่ยวข้องกับคำถามและคำตอบ
traktor53

@Flame_Phoenix พูดถึงมีปัญหาในรหัสนี้ โดยทั่วไปในการผ่านครั้งแรกคุณสร้างตัวจับเวลาจากนั้นวนซ้ำซ้ำแล้วซ้ำอีกเรื่อย ๆ จนกว่าลูปจะสิ้นสุดตามเงื่อนไข ( i < 10) ดังนั้นคุณจะมีตัวจับเวลาหลายตัวทำงานพร้อมกันซึ่งจะเป็นการสร้างการจัดสรรหน่วยความจำ
XCanG

63

เนื่องจาก ES7 มีวิธีที่ดีกว่าในการรอการวนซ้ำ:

// Returns a Promise that resolves after "ms" Milliseconds
function timer(ms) {
 return new Promise(res => setTimeout(res, ms));
}

async function load () { // We need to wrap the loop into an async function for this to work
  for (var i = 0; i < 3; i++) {
    console.log(i);
    await timer(3000); // then the created Promise can be awaited
  }
}

load();

เมื่อเครื่องยนต์ถึงawaitส่วนที่จะกำหนดหมดเวลาและหยุดการดำเนินการของ async functionจากนั้นเมื่อหมดเวลาการดำเนินการต่อไปที่จุดนั้น มีประโยชน์มากเพราะคุณสามารถหน่วงเวลา (1) ลูปซ้อนกัน, (2) ตามเงื่อนไข, (3) ฟังก์ชั่นที่ซ้อนกัน:

async function task(i) { // 3
  await timer(1000);
  console.log(`Task ${i} done!`);
}

async function main() {
  for(let i = 0; i < 100; i+= 10) {
    for(let j = 0; j < 10; j++) { // 1
      if(j % 2) { // 2
        await task(i + j);
      }
    }
  }
}
    
main();

function timer(ms) { return new Promise(res => setTimeout(res, ms)); }

อ้างอิง MDN

ในขณะที่ ES7 รองรับโดย NodeJS และเบราว์เซอร์ที่ทันสมัยคุณอาจต้องการtranspile ด้วย BabelJSเพื่อให้ทำงานได้ทุกที่


มันใช้งานได้ดีสำหรับฉัน ฉันแค่ต้องการถามว่าถ้าฉันต้องการที่จะทำลายวงฉันจะทำอย่างไรเมื่อใช้รอ?
Sachin Shah

@sachin break;อาจจะ?
Jonas Wilms

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

สิ่งนี้จะยังคงสร้างตัวจับเวลาที่หลากหลายและพวกเขาจะแก้ไขในเวลาที่แตกต่างกันมากกว่าในลำดับ?
David Yell

@JonasWilms ดูเหมือนว่าฉันพลาดปุ่ม 'Run snippet' ทั้งหมด: facepalm:
David Yell

24

อีกวิธีหนึ่งคือการคูณเวลาที่จะหมดเวลา แต่ทราบว่านี้ไม่ได้เช่นการนอนหลับ รหัสหลังจากวนรอบจะถูกดำเนินการทันทีเฉพาะการดำเนินการของฟังก์ชั่นการโทรกลับถูกเลื่อนออกไป

for (var start = 1; start < 10; start++)
    setTimeout(function () { alert('hello');  }, 3000 * start);

การหมดเวลาครั้งแรกจะถูกตั้งค่า3000 * 1เป็นครั้งที่สองไป3000 * 2เรื่อย ๆ


2
เป็นค่าชี้ให้เห็นว่าคุณไม่สามารถใช้startในการทำงานของคุณโดยใช้วิธีนี้ได้อย่างน่าเชื่อถือ
DBS

2
การปฏิบัติที่ไม่เหมาะสม - การจัดสรรหน่วยความจำที่ไม่จำเป็น
Alexander Trakhimenok

โหวตให้กับความคิดสร้างสรรค์ แต่มันเป็นการฝึกฝนที่ไม่ดี :)
Salivan

2
เหตุใดจึงเป็นวิธีปฏิบัติที่ไม่ดีและทำไมจึงมีปัญหาการจัดสรรหน่วยความจำ คำตอบนี้ประสบปัญหาเดียวกันหรือไม่? stackoverflow.com/a/36018502/1337392
Flame_Phoenix

1
@Flame_Phoenix เป็นการปฏิบัติที่ไม่ดีเพราะโปรแกรมจะเก็บหนึ่งตัวจับเวลาสำหรับแต่ละลูปโดยที่ตัวนับทั้งหมดทำงานในเวลาเดียวกัน ดังนั้นหากมีการวนซ้ำ 1,000 รอบจะมีตัวจับเวลา 1,000 ตัววิ่งพร้อมกันในตอนเริ่มต้น
โจอาคิม

16

สิ่งนี้จะได้ผล

for (var i = 0; i < 10; i++) {
  (function(i) {
    setTimeout(function() { console.log(i); }, 100 * i);
  })(i);
}

ลองเล่นซอนี้: https://jsfiddle.net/wgdx8zqq/


1
วิธีนี้จะทริกเกอร์การหมดเวลาใช้งานทั้งหมดในเวลาใกล้เคียงกัน
Eddie

สิ่งเดียวที่ฉันบอกว่าฉันแตกด้วยวิธีนี้ใช้$.Deferredแต่มันเป็นสถานการณ์ที่แตกต่างกันเพื่อให้มันใช้งานได้ยกนิ้วให้คุณ .. !
ArifMustafa

15

ฉันคิดว่าคุณต้องการอะไรแบบนี้:

var TimedQueue = function(defaultDelay){
    this.queue = [];
    this.index = 0;
    this.defaultDelay = defaultDelay || 3000;
};

TimedQueue.prototype = {
    add: function(fn, delay){
        this.queue.push({
            fn: fn,
            delay: delay
        });
    },
    run: function(index){
        (index || index === 0) && (this.index = index);
        this.next();
    },
    next: function(){
        var self = this
        , i = this.index++
        , at = this.queue[i]
        , next = this.queue[this.index]
        if(!at) return;
        at.fn();
        next && setTimeout(function(){
            self.next();
        }, next.delay||this.defaultDelay);
    },
    reset: function(){
        this.index = 0;
    }
}

รหัสทดสอบ:

var now = +new Date();

var x = new TimedQueue(2000);

x.add(function(){
    console.log('hey');
    console.log(+new Date() - now);
});
x.add(function(){
    console.log('ho');
    console.log(+new Date() - now);
}, 3000);
x.add(function(){
    console.log('bye');
    console.log(+new Date() - now);
});

x.run();

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


15

setIntevalผมก็อาจจะใช้ แบบนี้,

var period = 1000; // ms
var endTime = 10000;  // ms
var counter = 0;
var sleepyAlert = setInterval(function(){
    alert('Hello');
    if(counter === endTime){
       clearInterval(sleepyAlert);
    }
    counter += period;
}, period);

3
SetTimeout ดีกว่าการตั้งค่าช่วง google มันแล้วคุณจะรู้
Airy

14
ฉัน google มันประมาณเล็กน้อยและฉันพบว่าไม่มีอะไรทำไม setInterval ไม่ดี? คุณสามารถให้ลิงค์กับเราได้ไหม หรือตัวอย่าง? ขอบคุณ
Marcs

ฉันเดาว่าประเด็นคือการSetInterval()ทำให้ 'กระทู้' วางไข่แม้ในกรณีที่เกิดข้อผิดพลาดหรือบล็อก
Mateen Ulhaq

8

ใน ES6 (ECMAScript 2015) คุณสามารถทำซ้ำกับความล่าช้าด้วยตัวสร้างและช่วงเวลา

Generators เป็นคุณสมบัติใหม่ของ ECMAScript 6 ซึ่งเป็นฟังก์ชั่นที่สามารถหยุดชั่วคราวและทำงานต่อได้ การเรียกใช้ genFunc ไม่ดำเนินการ แต่จะส่งคืนวัตถุกำเนิดที่เรียกว่าช่วยให้เราควบคุมการทำงานของ genFunc แทน genFunc () ถูกระงับเริ่มต้นที่จุดเริ่มต้นของร่างกาย วิธีการ genObj.next () ยังคงดำเนินการของ genFunc จนกว่าจะได้ผลตอบแทนต่อไป (การสำรวจ ES6)


ตัวอย่างรหัส:

let arr = [1, 2, 3, 'b'];
let genObj = genFunc();

let val = genObj.next();
console.log(val.value);

let interval = setInterval(() => {
  val = genObj.next();
  
  if (val.done) {
    clearInterval(interval);
  } else {
    console.log(val.value);
  }
}, 1000);

function* genFunc() {
  for(let item of arr) {
    yield item;
  }
}

ดังนั้นหากคุณกำลังใช้ ES6 นั่นเป็นวิธีที่ดีที่สุดในการวนลูปด้วยความล่าช้า (สำหรับความคิดเห็นของฉัน)


4

คุณสามารถใช้ RxJS ประกอบการช่วงเวลา ช่วงเวลาปล่อยจำนวนเต็มทุก ๆ x จำนวนวินาทีและใช้เป็นการระบุจำนวนครั้งที่มีการปล่อยตัวเลข

Rx.Observable
  .interval(1000)
  .take(10)
  .subscribe((x) => console.log(x))
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.lite.min.js"></script>


4

แค่คิดว่าฉันโพสต์สองเซ็นต์ของฉันที่นี่เช่นกัน ฟังก์ชันนี้เรียกใช้การวนซ้ำแบบวนซ้ำพร้อมการหน่วงเวลา ดูjsfiddleนี้ ฟังก์ชั่นมีดังนี้:

function timeout(range, time, callback){
    var i = range[0];                
    callback(i);
    Loop();
    function Loop(){
        setTimeout(function(){
            i++;
            if (i<range[1]){
                callback(i);
                Loop();
            }
        }, time*1000)
    } 
}

ตัวอย่างเช่น:

//This function prints the loop number every second
timeout([0, 5], 1, function(i){
    console.log(i);
});

จะเทียบเท่ากับ:

//This function prints the loop number instantly
for (var i = 0; i<5; i++){
    console.log(i);
}

4

ฉันทำสิ่งนี้กับ Bluebird's Promise.delayและการเรียกซ้ำ

function myLoop(i) {
  return Promise.delay(1000)
    .then(function() {
      if (i > 0) {
        alert('hello');
        return myLoop(i -= 1);
      }
    });
}

myLoop(3);
<script src="//cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.4/bluebird.min.js"></script>


2

ใน ES6 คุณสามารถทำสิ่งต่อไปนี้:

 for (let i = 0; i <= 10; i++){       
     setTimeout(function () {   
        console.log(i);
     }, i*3000)
 }

ใน ES5 คุณสามารถทำได้ดังนี้:

for (var i = 0; i <= 10; i++){
   (function(i) {          
     setTimeout(function () {   
        console.log(i);
     }, i*3000)
   })(i);  
 }

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


1

คำตอบของ Daniel Vassallo เวอร์ชันที่ได้รับการแก้ไขซึ่งมีการแยกตัวแปรเป็นพารามิเตอร์เพื่อให้ฟังก์ชั่นนำกลับมาใช้ใหม่ได้มากขึ้น:

ก่อนอื่นเรามานิยามตัวแปรที่สำคัญกันบ้าง:

var startIndex = 0;
var data = [1, 2, 3];
var timeout = 3000;

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

function functionToRun(i, length) {
    alert(data[i]);
}

รุ่นที่ดำเนินการเอง

(function forWithDelay(i, length, fn, delay) {
   setTimeout(function () {
      fn(i, length);
      i++;
      if (i < length) {
         forWithDelay(i, length, fn, delay); 
      }
  }, delay);
})(startIndex, data.length, functionToRun, timeout);

รุ่นใช้งานได้

function forWithDelay(i, length, fn, delay) {
   setTimeout(function () {
      fn(i, length);
      i++;
      if (i < length) {
         forWithDelay(i, length, fn, delay); 
      }
  }, delay);
}

forWithDelay(startIndex, data.length, functionToRun, timeout); // Lets run it

หนึ่งที่ดีและฉันจะส่งข้อมูลไปยังฟังก์ชั่นที่ไม่มีตัวแปรทั่วโลกได้อย่างไร
Sundara Prabu


1

ที่คุณทำมัน:

console.log('hi')
let start = 1
setTimeout(function(){
  let interval = setInterval(function(){
    if(start == 10) clearInterval(interval)
    start++
    console.log('hello')
  }, 3000)
}, 3000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


ดีกว่าการบันทึกการใช้คอนโซลแทนการแจ้งเตือนไม่ได้สนุกมากที่จะปิดการแจ้งเตือนสำหรับครึ่งนาที;)
เฮ็นดรี

ใช่. ฉันเห็น! แต่คำขอจะมีการเตือน ... huz
เหงียน Ba Danh - FAIC HN

ทำไมต้องนำเข้า jQuery
Elias Soares

ขออภัย ... มันไม่จำเป็น .. ฉันไม่รู้จักเนื้อหาโพสต์ ... สิ่งนี้ก่อน
เหงียน Ba Danh - FAIC HN

0
/* 
  Use Recursive  and setTimeout 
  call below function will run loop loopFunctionNeedCheck until 
  conditionCheckAfterRunFn = true, if conditionCheckAfterRunFn == false : delay 
  reRunAfterMs miliseconds and continue loop
  tested code, thanks
*/

function functionRepeatUntilConditionTrue(reRunAfterMs, conditionCheckAfterRunFn,
 loopFunctionNeedCheck) {
    loopFunctionNeedCheck();
    var result = conditionCheckAfterRunFn();
    //check after run
    if (!result) {
        setTimeout(function () {
            functionRepeatUntilConditionTrue(reRunAfterMs, conditionCheckAfterRunFn, loopFunctionNeedCheck)
        }, reRunAfterMs);
    }
    else  console.log("completed, thanks");    
            //if you need call a function after completed add code call callback in here
}

//passing-parameters-to-a-callback-function
// From Prototype.js 
if (!Function.prototype.bind) { // check if native implementation available
    Function.prototype.bind = function () {
        var fn = this, args = Array.prototype.slice.call(arguments),
            object = args.shift();
        return function () {
            return fn.apply(object,
              args.concat(Array.prototype.slice.call(arguments)));
        };
    };
}

//test code: 
var result = 0; 
console.log("---> init result is " + result);
var functionNeedRun = function (step) {           
   result+=step;    
       console.log("current result is " + result);  
}
var checkResultFunction = function () {
    return result==100;
}  

//call this function will run loop functionNeedRun and delay 500 miliseconds until result=100    
functionRepeatUntilConditionTrue(500, checkResultFunction , functionNeedRun.bind(null, 5));

//result log from console:
/*
---> init result is 0
current result is 5
undefined
current result is 10
current result is 15
current result is 20
current result is 25
current result is 30
current result is 35
current result is 40
current result is 45
current result is 50
current result is 55
current result is 60
current result is 65
current result is 70
current result is 75
current result is 80
current result is 85
current result is 90
current result is 95
current result is 100
completed, thanks
*/

7
ชื่อฟังก์ชั่นของคุณมันช่างน่ากลัวนั่นเป็นสาเหตุหลักที่ทำให้รหัสนี้อ่านยาก
Mark Walters

0

นี่คือวิธีที่ฉันสร้างลูปไม่สิ้นสุดโดยมีความล่าช้าซึ่งแบ่งตามเงื่อนไขที่แน่นอน:

  // Now continuously check the app status until it's completed, 
  // failed or times out. The isFinished() will throw exception if
  // there is a failure.
  while (true) {
    let status = await this.api.getStatus(appId);
    if (isFinished(status)) {
      break;
    } else {
      // Delay before running the next loop iteration:
      await new Promise(resolve => setTimeout(resolve, 3000));
    }
  }

กุญแจสำคัญในที่นี้คือการสร้างสัญญาใหม่ที่แก้ไขได้โดยการหมดเวลาและรอการแก้ไข

เห็นได้ชัดว่าคุณต้องการ async / รอการสนับสนุนสำหรับสิ่งนั้น ใช้งานได้ในโหนด 8


0

สำหรับการใช้งานทั่วไป "ลืมลูปปกติ" และใช้การรวมกันของ "setInterval" นี้รวมถึง "setTimeOut" s: like this (จากงานจริงของฉัน)

        function iAsk(lvl){
            var i=0;
            var intr =setInterval(function(){ // start the loop 
                i++; // increment it
                if(i>lvl){ // check if the end round reached.
                    clearInterval(intr);
                    return;
                }
                setTimeout(function(){
                    $(".imag").prop("src",pPng); // do first bla bla bla after 50 millisecond
                },50);
                setTimeout(function(){
                     // do another bla bla bla after 100 millisecond.
                    seq[i-1]=(Math.ceil(Math.random()*4)).toString();
                    $("#hh").after('<br>'+i + ' : rand= '+(Math.ceil(Math.random()*4)).toString()+' > '+seq[i-1]);
                    $("#d"+seq[i-1]).prop("src",pGif);
                    var d =document.getElementById('aud');
                    d.play();                   
                },100);
                setTimeout(function(){
                    // keep adding bla bla bla till you done :)
                    $("#d"+seq[i-1]).prop("src",pPng);
                },900);
            },1000); // loop waiting time must be >= 900 (biggest timeOut for inside actions)
        }

PS: เข้าใจว่าพฤติกรรมที่แท้จริงของ (setTimeOut): พวกเขาทั้งหมดจะเริ่มในเวลาเดียวกัน "สาม bla bla bla จะเริ่มนับถอยหลังในช่วงเวลาเดียวกัน" ดังนั้นให้หมดเวลาที่แตกต่างกันเพื่อจัดการการดำเนินการ

PS 2: ตัวอย่างของการวนรอบเวลา แต่สำหรับการวนซ้ำของปฏิกิริยาคุณสามารถใช้เหตุการณ์ต่าง ๆ ได้สัญญา async กำลังรอ ..


0

<!DOCTYPE html>
<html>
<body>

<button onclick="myFunction()">Try it</button>

<p id="demo"></p>

<script>
function myFunction() {
    for(var i=0; i<5; i++) {
    	var sno = i+1;
       	(function myLoop (i) {          
             setTimeout(function () {   
             	alert(i); // Do your function here 
             }, 1000*i);
        })(sno);
    }
}
</script>

</body>
</html>


1
กรุณามักจะให้คำอธิบายสั้น ๆ ที่อย่างน้อยถึงโค้ดของคุณอย่างน้อยสำหรับคนอื่น ๆ เพื่อให้แน่ใจว่าคุณอยู่ที่คำถาม
Hexfire

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

0

สำหรับความรู้ของฉันsetTimeoutฟังก์ชั่นนี้เรียกว่าแบบอะซิงโครนัส สิ่งที่คุณสามารถทำได้คือล้อมรอบทั้งลูปภายในฟังก์ชัน async และรอPromiseที่มี setTimeout ดังแสดง:

var looper = async function () {
  for (var start = 1; start < 10; start++) {
    await new Promise(function (resolve, reject) {
      setTimeout(function () {
        console.log("iteration: " + start.toString());
        resolve(true);
      }, 1000);
    });
  }
  return true;
}

จากนั้นคุณเรียกใช้มันเหมือน:

looper().then(function(){
  console.log("DONE!")
});

โปรดสละเวลาสักครู่เพื่อทำความเข้าใจเกี่ยวกับการเขียนโปรแกรมแบบอะซิงโครนัส


0

ลองแค่นี้สิ

 var arr = ['A','B','C'];
 (function customLoop (arr, i) {
    setTimeout(function () {
    // Do here what you want to do.......
    console.log(arr[i]);
    if (--i) {                
      customLoop(arr, i); 
    }
  }, 2000);
})(arr, arr.length);

ผลลัพธ์

A // after 2s
B // after 2s
C // after 2s

-1

นี่คือฟังก์ชั่นที่ฉันใช้สำหรับการวนลูปมากกว่าอาร์เรย์:

function loopOnArrayWithDelay(theArray, delayAmount, i, theFunction, onComplete){

    if (i < theArray.length && typeof delayAmount == 'number'){

        console.log("i "+i);

        theFunction(theArray[i], i);

        setTimeout(function(){

            loopOnArrayWithDelay(theArray, delayAmount, (i+1), theFunction, onComplete)}, delayAmount);
    }else{

        onComplete(i);
    }
}

คุณใช้มันแบบนี้:

loopOnArrayWithDelay(YourArray, 1000, 0, function(e, i){
    //Do something with item
}, function(i){
    //Do something once loop has completed
}

-1

สคริปต์นี้ใช้ได้กับทุกสิ่ง

function timer(start) {
    setTimeout(function () { //The timer
        alert('hello');
    }, start*3000); //needs the "start*" or else all the timers will run at 3000ms
}

for(var start = 1; start < 10; start++) {
    timer(start);
}

-1

ลองสิ่งนี้ ...

var icount=0;
for (let i in items) {
   icount=icount+1000;
   new beginCount(items[i],icount);
}

function beginCount(item,icount){
  setTimeout(function () {

   new actualFunction(item,icount);

 }, icount);
}

function actualFunction(item,icount){
  //...runs ever 1 second
 console.log(icount);
}

-1

ใช้งานง่ายในการแสดงชิ้นส่วนของข้อความทุก ๆ สองวินาทีตราบใดที่ลูปทำงาน

for (var i = 0; i < foo.length; i++) {
   setInterval(function(){ 
     console.log("I will appear every 2 seconds"); 
   }, 2000);
  break;
};

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