javascript - For循环无限运行
问题描述
所以我已经和这个 for 循环斗争了一天半了,当我让它实际打印时它会无限运行,即使 if 语句 (logCount === 10) 得到满足......不太确定该尝试什么再说了,真的觉得它比我尝试的要简单得多......
任何解决方案的尝试都值得赞赏..
var timers = [];
var log = (function(outputFunc) {
var counter = 0;
var callerLog = [];
var dateTime = [];
//assigning current Date to a variable to print for logs
let logDate = new Date();
return function(timer) {
for (var logCount = 0; logCount <= 10; logCount++) {
//printing data without using printFunc, as specified
document.getElementById("output").innerHTML += logCount + " " + timer + " " + logDate + "<br>";
//TODO: add after for loop is resolved.
if (logCount >= 10) {
clearInterval(timer1);
clearInterval(timer2);
clearInterval(timer3);
document.getElementById("output").innerHTML += "<br><br/> Logging stopped.";
}
}
}
})(printFunc);
function printFunc(output) {
document.write(output + "<br>");
}
function startMeUp() {
// add each of the timer references to the timers array
// as part of invoking the log function following each interval
timers.push(setInterval("log('Timer1')", 1000));
timers.push(setInterval("log('Timer2')", 1200));
timers.push(setInterval("log('Timer3')", 1700));
}
解决方案
我猜这就是你想要实现的目标:
function printFunc(output) {
// Replaced with console.log for my own convenience
console.log(output);
}
// Not really a factory, just a curry of the outputFunc
function loggerFactory(outputFunc) {
return function startLogger(name, interval) {
// Variables to keep track of the iterations and a reference to the interval to cancel
let logCount = 0;
let intervalRef;
function tick() {
// On each tick, check if we're done
// If yes, clear the interval and do the last output
// If no, do some output and increment the iterator
// Once the next tick passes we'll check again
// If you were using setTimeout instead you would have to requeue the tick here
if (logCount >= 10) {
clearInterval(intervalRef);
outputFunc('Done ' + name);
} else {
outputFunc(logCount + " " + name);
logCount += 1;
}
}
// Start it of
intervalRef = setInterval(tick, interval);
}
}
const logger = loggerFactory(printFunc);
function startMeUp() {
console.log('Starting');
logger('Log1', 1000);
logger('Log2', 1200);
logger('Log3', 1700);
}
startMeUp();
一些注意事项:您可以将 intervalRefs 推送到一个数组中,但我发现将这些工作封装在同一个记录器中会更好,因为它应该只清理自己。
当使用间隔(或一般的异步代码)时,for 循环通常不是您想要的。for 循环本质上是同步的,所有迭代将直接在彼此之后运行,没有其他任何空间。您正在寻找的是一种同时运行多个异步“轨道”的方法。您可以使用 for 循环来启动这些“轨道”,例如:
for () {
logger('Log' + i, 1000 * i);
}
但关键在于logger快速设置了interval函数,然后返回。这样,您的 for 循环可以快速“调度”任务,但记录器使用 setInterval 或 setTimeout 在内部异步运行迭代。
推荐阅读
- r - 运行闪亮的应用程序时如何仅运行特定的mac地址
- php - 使用没有图像名称的父目录在 html 页面上显示图像
- r - ggplot2 - 如何替换图例中的几何符号?
- javascript - 在谷歌网络应用脚本中使用three.js - 无法使用脚本模块类型加载three.js
- reactjs - React - 当浏览器开始绘制或重新绘制哪个生命周期方法结束时?
- java - 请高中需要帮助;将输出写入文件(使用距离程序)?
- ios - App Store Connect 操作错误:密钥 com.apple.developer.healthkit.access 的 ITMS-90164 []
- html - 如何使按钮中的字体真棒图标可点击?
- java - LibGDX - 只有一半的屏幕是活动的游乐场
- numpy - 在 numpy 中,分别将 N 个百分位数应用于 N x M 数组