我有一个不同对象的数组,每个对象包含不同值的时间属性。
我想为这个数组循环,里面有一个setTimeout函数,时间将是每个对象的时间属性。
所以,我想要的结果是
然而,下面的代码将在总共20秒的累积中执行,这就是打印obj3&; 5当时间=5s时,5s后打印obj1,10s后打印obj2& 4。
const data = [
{name: "Warm up", timeFormat: "00:10", time: 10},
{name: "High interval", timeFormat: "00:20", time: 20},
{name: "Low Interval", timeFormat: "00:05", time: 5},
{name: "High interval", timeFormat: "00:20", time: 20},
{name: "Low Interval", timeFormat: "00:05", time: 5},
]
function renderTimer(data) {
for (let i = 0; i < data.length; i++) {
const eachName = data[i].name;
const eachTime = data[i].time;
setTimeout(() => {
console.log(eachName);
}, eachTime * 1000);
}
}
renderTimer(data);
我的代码有什么问题? 或者其他任何方式来达到我想要的结果?
非常感谢!
所发生的情况是,程序在for循环中快速运行,并几乎立即设置相对于t=0s的超时。 如果要使用setTimeout(),则必须自己累积计时:
null
const data = [
{name: "Warm up", timeFormat: "00:10", time: 10},
{name: "High interval", timeFormat: "00:20", time: 20},
{name: "Low Interval", timeFormat: "00:05", time: 5},
{name: "High interval", timeFormat: "00:20", time: 20},
{name: "Low Interval", timeFormat: "00:05", time: 5},
]
function renderTimer(data) {
var timing = 0;
for (let i = 0; i < data.length; i++) {
const eachName = data[i].name;
timing += data[i].time;
setTimeout(() => {
console.log(eachName);
}, timing * 1000);
}
}
renderTimer(data);
您可以使用async
/await
和promise
s来执行此操作
它使用Await new Promise(。。。)
停止当前函数直到Promise实现
null
const data = [
{name: "Warm up", timeFormat: "00:10", time: 10},
{name: "High interval", timeFormat: "00:20", time: 20},
{name: "Low Interval", timeFormat: "00:05", time: 5},
{name: "High interval", timeFormat: "00:20", time: 20},
{name: "Low Interval", timeFormat: "00:05", time: 5},
]
async function renderTimer(data) {
for (let i = 0; i < data.length; i++) {
const eachName = data[i].name;
const eachTime = data[i].time;
await new Promise(res => {
setTimeout(() => {
console.log(eachName);
// resolve the promise once the log is done
res()
}, eachTime * 100)}
)
// can't arrive here until the setTimeout is finalized
}
}
renderTimer(data);
您也可以在递归函数中这样做:
null
const data = [
{name: "Warm up", timeFormat: "00:10", time: 10},
{name: "High interval", timeFormat: "00:20", time: 20},
{name: "Low Interval", timeFormat: "00:05", time: 5},
{name: "High interval", timeFormat: "00:20", time: 20},
{name: "Low Interval", timeFormat: "00:05", time: 5},
]
const renderTimer = (data, i = 0) => {
setTimeout(() => {
console.log(data[i].name);
// Call for next data
if(i < data.length - 1)
renderTimer(data, i + 1);
}, data[i].time * 1000);
}
renderTimer(data);