2016-12-28 9 views
0

Javascriptでは、以下のようなコードを書くと、コンピュータが最初にループ100 000回(2〜2回かかることがあります)を完了し、その後100,000行すべてをコンソールにダンプするようですワンショットで。どのようにすれば、コンピュータが一度に1行ずつ、ループを通過するごとにコンソールを更新するのですか?Javascriptでコンソールにリアルタイムで出力するには?

明確にするために、私は実際にコンピュータが何をしているのかを見ることができるようにしたいと思います。

for (var i = 1; i <= 100000; i++) { 
 
    console.log(i); 
 
}

+2

? Javascriptは多くの異なる場所で実行され、 'consoleの実装はさまざまです。log' –

+1

クロムデベロッパーツールを開き、コンソールに切り替え、そのコードを、???、利益に貼り付けてください! – imjared

+1

私は、何らかの起動遅延がある環境で作業していると感じています。たとえロギングが完了する前にループが完全に実行されたとしても、わずか10万の反復で検出可能な時間がかかりません。 –

答えて

2

ブラウザはスクリプトを同期して実行します。ロングタスクが実行されているときにページを更新するには、長時間実行される同期コードを分割し、これらの処理の間にブラウザに制御を委譲する必要があります。これは、一連のタスクをチャンクに分割し、ブラウザに制御を戻す遅延を制御する必要があることを意味します。

これを行う方法を提供するスニペットがあります。パフォーマンスはそれほど素晴らしいわけではありませんが、これは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); } 
 
});

-1

あなたの文は有効ではありません。 JavaScriptはforループを同期して処理します。

次の質問を確認してください:あなたがスムーズな出力をしたい場合は、私はforループを回避示唆し、代わりに結果をプリントアウトする際に管理されますどの​​を使用することになりJavaScript, Node.js: is Array.forEach asynchronous?

+1

これは本当に質問とは関係ありません。問題は、ループが完了した後ではなく、 'console.log'が即座に出力できるかどうかの行に沿っています。答えは、それが環境に依存するということです。たとえば、node.jsを使用すると、次のようになります。http://stackoverflow.com/a/27900423/2101267 –

+0

@DarkFalcon console.logはすぐにログに記録されます。 – tomepejo

0

を。ここ

var counter = 0; 
var max = 100000; 
function myPrint(){ 
    if(counter < max){ 
     console.log(counter++); 
     requestAnimationFrame(myPrint); 
    } 
} 
myPrint(); 
+1

私は 'requestAnimationFrame'をグラフィカルな更新と無関係のものには使用しません。 –

+0

私は同意する、それは最善の提案ではない。私は 'requestAnimationFrame'がnodeJSでは動作しないと付け加えるべきです。 – bobjoe

0

for (let i = 1; i <= 10; i++) { 
 
    //console.log(i); 
 
    setTimeout(function(){console.log(i)},i*1000); 
 
}

あなたのコンソールを遅らせることができる方法です。 setTimeoutを使用してconsole.log値の値を1秒(1000ms)後に確認します。

letは、使用されているブロック、ステートメント、または式に範囲が限定された変数を宣言できます。これは、変数をグローバルに定義するvarキーワードとは異なり、ブロックスコープに関係なく関数全体に対してローカルに定義されます。

+0

それはある種のハックですが、私はそれをある状況で利用することができます。面白い結果が得られるまで時間を10msに変更してみてください。 – neoflash

+0

は10msで高速に読み込み、結果は変わりません。あなたはクロムを使っていますか? – jindhk

+0

はい、クロム。 JSfiddleで試してみましょう。順番にすべてを印刷するわけではありません。 – neoflash

0

一つは、所望の結果を達成するために観測することを約束のアレイを養うことができました。約束はJavaScriptのネイティブになっており、ObservableはRxJSライブラリから入手できます。ここで

は一例です:どのような環境では

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>

関連する問題