在Javascript中,当您编写如下所示的一段代码时,似乎计算机将首先完成整个循环100 000次(可能需要一两秒钟),然后在控制台中转储所有100 000行一枪。我该如何做到这一点,使计算机一次更新控制台一行,每次通过循环?如何在Javascript中实时输出到控制台?
为了澄清,我想实际上能够看到计算机正在做什么,而不是一旦它完成了。
for (var i = 1; i <= 100000; i++) {
console.log(i);
}
在Javascript中,当您编写如下所示的一段代码时,似乎计算机将首先完成整个循环100 000次(可能需要一两秒钟),然后在控制台中转储所有100 000行一枪。我该如何做到这一点,使计算机一次更新控制台一行,每次通过循环?如何在Javascript中实时输出到控制台?
为了澄清,我想实际上能够看到计算机正在做什么,而不是一旦它完成了。
for (var i = 1; i <= 100000; i++) {
console.log(i);
}
浏览器同步运行脚本。如果您希望在长期任务运行时更新页面,则需要将长时间运行的同步代码分解为多个部分,并在处理这些部分时将控制权交给浏览器。这意味着您需要处理将一系列任务分解为块,并控制将控制返回给浏览器的延迟。
这里有一个片段,它提供了一个方法,可以让你做到这一点!您会注意到性能仍然不是很好,但我确信这是由于stackoverflow的嵌入式脚本运行器的实现缓慢(console.log
)。尝试在浏览器的实际控制台中使用此代码 - 性能非常好!
function doHeavyTask(params) {
var totalMillisAllotted = params.totalMillisAllotted;
var totalTasks = params.totalTasks;
var tasksPerTick = params.tasksPerTick;
var tasksCompleted = 0;
var totalTicks = Math.ceil(totalTasks/tasksPerTick);
var interval = null;
if (totalTicks === 0) return;
var doTick = function() {
var totalByEndOfTick = Math.min(tasksCompleted + tasksPerTick, totalTasks);
do {
params.task(tasksCompleted++);
} while(tasksCompleted < totalByEndOfTick);
if (tasksCompleted >= totalTasks) clearInterval(interval);
};
// Tick once immediately, and then as many times as needed using setInterval
doTick();
if (totalTicks > 1) interval = setInterval(doTick, totalMillisAllotted/totalTicks);
}
// Do 10,000 console.logs, in chunks of 100, within 5 seconds
doHeavyTask({
totalMillisAllotted: 5 * 1000,
totalTasks: 10000,
tasksPerTick: 100,
task: function(n) { console.log(n + 1); }
});
你的声明是无效的。 JavaScript同步处理for
循环。
这与问题没有关系。问题更多的是是否可以立即输出console.log,而不是在循环完成后输出。答案是它取决于环境。例如,使用node.js,是的,它可以:http://stackoverflow.com/a/27900423/2101267 –
@DarkFalcon console.log即刻登录。 – tomepejo
如果你想更平滑的输出,我建议避免for循环,而是使用将管理时,打印出结果。
var counter = 0;
var max = 100000;
function myPrint(){
if(counter < max){
console.log(counter++);
requestAnimationFrame(myPrint);
}
}
myPrint();
我不会将'requestAnimationFrame'用于与图形更新无关的任何事情。 –
我同意,这不是最好的建议。我应该补充说'requestAnimationFrame'在nodeJS中不起作用。 – bobjoe
for (let i = 1; i <= 10; i++) {
//console.log(i);
setTimeout(function(){console.log(i)},i*1000);
}
这里是你如何能耽误您的控制台。使用setTimeout检查1秒(1000毫秒)后console.log值的值。
let允许您将范围受限的变量声明为块,语句或使用它的表达式。这与var关键字不同,var关键字全局定义变量,或在本地定义整个函数,而不考虑块范围。
人们可以以达到期望的结果馈送承诺的阵列到可观察。 Promise现在是JavaScript的原生代码,您可以从RxJS库中获取Observable。
下面是一个例子:
const array = [];
// This could also be a for of loop or a .map() function
for (let i = 0; i <= 25; i++) {
const promise = new Promise((resolve) => {
// This could be any synchronous or asynchronous code
setTimeout(() => {
resolve(i);
}, 1000 * i);
});
array.push(promise);
}
var observable = Rx.Observable.from(array);
observable.subscribe((promise) => {
promise.then(result => console.log(result));
});
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
在什么样的环境? Javascript运行在很多不同的地方,有很多不同的'console实现。日志' –
打开chrome开发工具,切换到控制台,粘贴该代码,???,获利! – imjared
我有一种感觉,你在一个有某种启动延迟的环境中工作。即使循环完全在任何日志记录完成之前运行,仅100,000次迭代就不会花费可察觉的时间量... –