簡體   English   中英

如何在 js 中循環遍歷字符串列表並同時降低循環速度?

[英]How do I loop trough a list of strings and decrease the looping speed at the same time in js?

我想創建一個 javascript,它循環遍歷所有名稱,並始終在 UI (html) 中顯示循環的當前名稱。 但與此同時,環路速度應該會降低。

所以假設我們以 10 次循環/秒的速度開始。 然后它應該減少直到它的 1 循環/秒,然后在那個點停止並顯示名稱。 它是一種抽獎活動,獲勝者應該是隨機的。

所以我創建了下面的腳本,但問題是沒有任何反應? 不知何故,什么都沒有發生。 它執行代碼但沒有錯誤,UI 也沒有任何變化。 代碼確實被執行了(通過登錄到控制台來測試它)!

我的功能:

function Roll(){
    var delay = 100;
    for(var i = 0; delay < 1000; i++){
        delay += 25;
        if(i >= listOfParticipants.length){
            i = 0;
        }
        setTimeout(function() {
            document.getElementById("person_name").value = listOfParticipants[i];
        }, delay);
    }
}

html元素:

<h1 class="text-center mt-2" id="person_name" ></h1>

編輯:我想我知道問題是什么,但我不知道如何解決。 我認為 for 循環不會等待 setTimeout 完成。 不知道怎么處理。

編輯 2:似乎 setTimeout 創建了一個新的 ExecutionContext。 這意味着 for 循環結束並在 setTimeout 執行之前獲得最大值 (13)。 現在的問題是如何在當前的 ExecutionContext 中添加超時? 該列表只有 12 個對象,這就是為什么 i = 13 的結果未定義的原因。

假設您想停在數組的姓氏上(因為在您的問題中不清楚名稱選擇應該如何工作),您可以使用一種策略。

基本上,您不想遍歷持續時間,而是希望遍歷listOfParticipants數組 在每次迭代中,我們減少在繼續 for 循環的下一次迭代之前等待的持續時間。

// Pseudo code!
async function roll() {
  for (let i = 0; i < listOfParticipants.length; i++) {
    // Wait for promise to resolve
    await someKindOfPromise();

    // Update name
    document.getElementById('person_name').innerText = listOfParticipants[i];
  }
}

這可以使用async/await來完成。 ES6 中的原生 for 循環支持等待承諾,因此我們只需創建一個方法,該方法返回在x秒后解析的承諾:

// A simple promise that resolves after a specified duration
function wait(duration) {
  return new Promise(resolve => {
    window.setTimeout(resolve, duration);
  });
}

x次通過后,我們繼續進行下一次迭代。

x的值可以簡單地通過基於我們沿參與者數組的相對位置遞減預設持續時間來確定。 您在數組中的位置越遠(由索引i表示),您希望時間越短,即: delay * i / listOfParticipants.length;

async function roll() {
  const delay = 100;
  for (let i = 0; i < listOfParticipants.length; i++) {
    // Force the for loop to wait for a set amount of time
    const duration = delay * i / listOfParticipants.length;
    await wait(duration);

    // Once the duration has been awaited, we can then update the inner text
    document.getElementById('person_name').innerText = listOfParticipants[i];
  }
}

請參閱下面的概念驗證:

 const listOfParticipants = ['Adena', 'Socorro', 'Germaine', 'Ebony', 'Raul', 'Anton', 'Rochel', 'Morgan', 'Joanie', 'Ellsworth', 'Edelmira', 'Susannah', 'Gino', 'Vicenta', 'Katrina', 'Devorah', 'Olinda', 'Lise', 'Napoleon', 'Dessie', 'Herta', 'Cassaundra', 'Nadine', 'Dalton', 'Mica', 'Haydee', 'Linh', 'Williemae', 'Desiree', 'Philomena', 'Julio', 'Darell', 'Shana', 'Ligia', 'Melita', 'Laurene', 'Darby', 'Gregg', 'Shemika', 'Tesha', 'Benita', 'Hyman', 'Kattie', 'Mary', 'Julienne', 'Claud', 'Heather', 'Toney', 'Vasiliki', 'Stephani', 'Violette', 'Barney', 'Warren', 'Felix', 'Mathew', 'Blair', 'Jamar', 'Grover', 'Bud', 'Barbie', 'Gina']; // A simple promise that resolves after a specified duration function wait(duration) { return new Promise(resolve => { window.setTimeout(resolve, duration); }); } async function roll() { const delay = 100; for (let i = 0; i < listOfParticipants.length; i++) { // Force the for loop to wait for a set amount of time const duration = delay * i / listOfParticipants.length; await wait(duration); // Once the duration has been awaited, we can then update the inner text document.getElementById('person_name').innerText = listOfParticipants[i]; } } document.querySelector('#btn').addEventListener('click', () => roll());
 <h1 class="text-center mt-2" id="person_name"></h1> <button id="btn">Raffle</button>

您可以遞歸調用setTimeout()而不是使用循環:

<h1 class="text-center mt-2" id="person_name" ></h1>
var listOfParticipants = [
  "Kurt",
  "Dave",
  "Krist",
  "Alanis",
  "Aimee",
  "Chris",
  "Eddie",
  "Mike",
  "Stone",
  "Jeff",
  "Matt",
  "Boom"
]

function doIt(i) {
  var participant = listOfParticipants[i];
  if (!participant) return;

  document.getElementById("person_name").innerHTML = participant;
  setTimeout(
    function() { 
      doIt(i + 1);
    }, 
    100 + i * 100
  );
}

doIt(0);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM