Javascript-循环中的异步/等待计时器



我正在处理一个"时间块";类型应用程序(适用于uni(。核心思想是我们有一个子任务列表,每个子任务都有指定的时间余量。我希望能够迭代完成任务,使用计时器倒计时分配的时间,然后迭代到下一个任务。例如

var todos = [
{ id: 1, task: "Finance", time: 1 },
{ id: 2, task: "Distribution", time: 1 },
{ id: 3, task: "Blah", time: 1 }
];

我们将重复上面的内容,在控制台中每个倒数1分钟。

我已经对核心功能进行了编码,迭代本身使用async/await。

此处为stackblitz:

https://stackblitz.com/edit/js-87ykxt

然而,在第一次迭代后,倒计时本身并不能正常工作,而且表现得很奇怪,似乎每秒倒计时两次,然后从未真正停止并进入负值。间隔应该在计时器每次达到0时清除,然后在下一次迭代发生时重新创建。

感谢您的帮助。

第页。S.还要注意,第一次迭代需要1分钟才能开始,我也必须解决这个问题!

好吧,我会避免使用全局变量。最好将参数/值作为参数传递给函数。请使用"let"one_answers"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");
}
}

这就是你可以做的,为了更好地演示,我将计时器设置为5s而不是60s:

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

最新更新