[英]Javascript - Async/Await Timer in loop
我正在開發“Timeblocks”類型的應用程序(用於 uni)。 核心思想是我們有一個子任務列表,每個子任務都有指定的時間限制。 我希望能夠遍歷任務,使用計時器對分配的時間進行倒計時,然后迭代到下一個任務。 例如;
var todos = [
{ id: 1, task: "Finance", time: 1 },
{ id: 2, task: "Distribution", time: 1 },
{ id: 3, task: "Blah", time: 1 }
];
我們將遍歷上述內容,在控制台中每個倒計時 1 分鍾。
我已經對核心功能進行了編碼,迭代本身與 async/await 一起工作。
堆棧閃電戰:
https://stackblitz.com/edit/js-87ykxt
然而,倒計時本身在第一次迭代后不能正常工作,並且表現得很奇怪,似乎每秒倒計時兩次,然后實際上從未停止並進入負數。 間隔應該在每次計時器達到 0 時清除,然后在下一次迭代發生時重新創建。
任何幫助表示贊賞。
PS 還知道第一次迭代需要 1 分鍾才能開始,我也必須解決這個問題!
好吧,我會避免使用全局變量。 最好將參數/值作為 arguments 傳遞給函數。 請使用 'let' 和 'const' 而不是 'var'。 為了幫助您理解我已經縮短了您的代碼並添加了一些調試行:希望現在它可以按照您的意願運行(:
// Import stylesheets
import "./style.css";
// Write Javascript code!
const start = document.getElementById("start");
start.addEventListener("click", startHandler);
var todos = [
{ id: 1, task: "Finance", time: 0.1 },
{ id: 2, task: "Distribution", time: 0.2 },
{ id: 3, task: "Blah", time: 0.2 }
];
var interval;
var mySeconds;
function tick(task, resolve) {
var min = Math.floor(mySeconds / 60);
var sec = mySeconds - min * 60;
if (sec < 10) {
sec = "0" + sec;
}
var message = min.toString() + ":" + sec;
console.log(message);
if (mySeconds === 0) {
alert("Done for " + task);
clearInterval(interval);
return resolve();
}
mySeconds--;
}
function resolveTimer(time, task) {
return new Promise(resolve => {
mySeconds = time;
interval = setInterval(tick, 1000, task, resolve);
});
}
async function startHandler() {
for (let i = 0; i < todos.length; i++) {
const time = todos[i].time;
const task = todos[i].task;
console.log("Starting for task:", task);
await resolveTimer(time * 60, task);
console.log(task, " awaited");
}
}
您可以這樣做,我將計時器設置為 5 秒而不是 60 秒,以便更好地演示:
const todos = [{ id: 1, task: "Finance", time: 1 }, { id: 2, task: "Distribution", time: 1 }, { id: 3, task: "Blah", time: 1 } ]; const taskDuration = 5; // 5 instead of 60 async function startHandler() { for (const todo of todos) { console.log('Current todo', todo.task); await countDown(todo.time * taskDuration); } } startHandler(); function countDown(time) { function tick() { const min = Math.floor(time / 60); let sec = time - min * 60; if (sec < 10) { sec = "0" + sec; } const message = min.toString() + ":" + sec; console.log(message); time--; } const interval = setInterval(tick, 1000); return promiseSetTimeout(() => clearInterval(interval), time * 1000); } // Util function to call a function later, and return a Promise function promiseSetTimeout(fun, time) { return new Promise(resolve => setTimeout(() => [fun, resolve].forEach(x => x.call()), time)); }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.