在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次迭代就不會花費可察覺的時間量... –