私は個人的なニーズのためのスクリプトのようなコンソールを開発しています。私は長時間休止できるようにする必要があります、しかし、私の調査から、node.jsは必要に応じて止める方法がありません。しばらくすると、ユーザーの情報を読みにくくなります。コードが表示されていますが、次のように機能するには他のコードを内部に配置する必要があると考えています。
setTimeout(function() {
}, 3000);
しかし、このコード行の後に、一定期間後に実行するすべてのものが必要です。
例えば、
//start-of-code
console.log('Welcome to My Console,');
some-wait-code-here-for-ten-seconds..........
console.log('Blah blah blah blah extra-blah');
//endcode.
こんなものも見ました
yield sleep(2000);
しかし、node.jsはこれを認識しません。
どうすればこの一時停止を延長できますか?
これを行う最善の方法は、コードを次のように複数の関数に分割することです。
function function1() {
// stuff you want to happen right away
console.log('Welcome to My Console,');
}
function function2() {
// all the stuff you want to happen after that pause
console.log('Blah blah blah blah extra-blah');
}
// call the first chunk of code right away
function1();
// call the rest of the code and have it execute after 3 seconds
setTimeout(function2, 3000);
これは JohnnyHK のソリューションに似ていますが、はるかに洗練されていて拡張が簡単です。
古い質問に対する新しい答えです。今日(2017年1月)、それはずっと簡単です。 new async/await
構文 を使用できます。例えば:
async function init(){
console.log(1)
await sleep(1000)
console.log(2)
}
function sleep(ms){
return new Promise(resolve=>{
setTimeout(resolve,ms)
})
}
インストールやプラグインをせずにasync/await
をそのまま使用するには、--harmony
フラグを使用してnode-v7またはnode-v8を使用する必要があります。
詳細情報:
遅延後に実行したいコードをsetTimeout
コールバック内に置きます。
console.log('Welcome to My Console,');
setTimeout(function() {
console.log('Blah blah blah blah extra-blah');
}, 3000);
これは簡単なブロックテクニックです。
var waitTill = new Date(new Date().getTime() + seconds * 1000);
while(waitTill > new Date()){}
スクリプトで他に何も起こらない限り(コールバックのように)、 ブロッキング /です。しかし、これはコンソールスクリプトなので、多分それはあなたが必要としているものです!
function sleep(millis) {
return new Promise(resolve => setTimeout(resolve, millis));
}
依存関係もコールバック地獄もありません。それでおしまい :-)
質問で与えられた例を考えると、これは2つのコンソールログの間でどのようにスリープするかです:
async function main() {
console.log("Foo");
await sleep(2000);
console.log("Bar");
}
main();
「欠点」は、あなたのメイン関数がasync
でなければならないことです。しかし、あなたがすでに現代のJavascriptコードを書いていることを考えると、あなたはおそらく(あるいは少なくともそうすべきです!)あなたのコード全体にasync
/await
を使っているので、これは実際問題ではありません。今日のすべての最近のブラウザは サポート それです。
async/await
と太い矢印の演算子に慣れていない人のためにsleep
関数について少し洞察を与えて、これはそれを書くための冗長な方法です:
function sleep(millis) {
return new Promise(function (resolve, reject) {
setTimeout(function () { resolve(); }, millis);
});
}
太い矢印演算子を使用すると、さらに小さくなります(そしてよりエレガントになります)。
あなたはこれを使用することができます www.npmjs.com/package/sleep
var sleep = require('sleep');
sleep.sleep(10); // sleep for ten seconds
依存関係のない最短の解決策:
await new Promise(done => setTimeout(done, 5000));
ノードは待機をネイティブにサポートします。
const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs));
あなたは非同期関数を使用することができれば:
await sleep(10000); // sleep for 10 seconds
または
sleep(10000).then(() => {
// This will execute 10 seconds from now
});
私は、長いwhileループでCPUを占有することなく、WindowsとLinuxで動作する非同期スリープを望みました。私はsleepパッケージを試しましたが、Windowsボックスにはインストールされませんでした。私は使用してしまいました:
https://www.npmjs.com/package/system-sleep
インストールするには、次のように入力します。
npm install system-sleep
あなたのコードでは、
var sleep = require('system-sleep');
sleep(10*1000); // sleep for 10 seconds
魅力のように働きます。
この質問はかなり古いですが、最近V8は、OPが要求したことを達成できるジェネレータを追加しました。ジェネレータは一般的に suspend または gen-run のようなライブラリの助けを借りた非同期インタラクションに最も使いやすいです。
これはsuspendを使った例です:
suspend(function* () {
console.log('Welcome to My Console,');
yield setTimeout(suspend.resume(), 10000); // 10 seconds pass..
console.log('Blah blah blah blah extra-blah');
})();
関連読書(恥知らずな自己宣伝として): 発電機との大したことは何ですか? 。
Linux/nodejsではこれは私のために働く:
const spawnSync = require( 'child_process')。spawnSync;
var sleep = spawnSync( 'sleep'、[1.5]);
ブロックしていますが、ビジーな待機ループではありません。
指定する時間は秒単位ですが、少しでもかまいません。他のOSにも同様のコマンドがあるかどうかわかりません。
私は最近、同期モードで非同期関数を呼び出すために wait.for と呼ばれるより単純な抽象化を作成しました(ノードファイバーに基づく)。今後のES6ジェネレーターに基づくバージョンもあります。
https://github.com/luciotato/waitfor
wait.for を使用すると、標準のnodejs async関数を、あたかもsync関数であるかのように、ノードのイベントループをブロックすることなく呼び出すことができます。
必要に応じて順番にコーディングすることができます。つまり、個人的な使用のためにスクリプトを単純化するのに最適です。
wait.for を使用すると、コードは次のようになります。
require('waitfor')
..in a fiber..
//start-of-code
console.log('Welcome to My Console,');
wait.miliseconds(10*1000); //defined in waitfor/paralell-tests.js - DOES NOT BLOCK
console.log('Blah blah blah blah extra-blah');
//endcode.
任意の非同期関数もSyncモードで呼び出すことができます。例を確認してください。
あなたが「コードゴルフ」をしたいならば、あなたはここで他の答えのいくつかのより短いバージョンを作ることができます:
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
しかし、私の意見では本当に理想的な答えは、Nodeのutil
ライブラリとそのpromisify
関数を使用することです。
const util = require('util');
const sleep = util.promisify(setTimeout);
どちらの場合も、await
を使用してsleep
関数を呼び出すだけで一時停止できます。
await sleep(1000); // sleep for 1s/1000ms
Javascriptエンジン(v8)はイベントキュー内のイベントのシーケンスに基づいてコードを実行するので、javascriptが指定された時間の後に正確に実行をトリガーすることは厳密ではありません。つまり、後でコードを実行するように数秒を設定した場合、トリガーコードは純粋にイベントキュー内のシーケンスに基づいています。そのため、コードの実行をトリガーするのに指定された時間以上かかることがあります。
それでNode.jsが続きます、
process.nextTick()
後でコードを実行する場合はsetTimeout()を使用してください。例えば、
process.nextTick(function(){
console.log("This will be printed later");
});
ES6はPromise
をサポートしているので、サードパーティの支援なしでそれらを使用できます。
const sleep = (seconds) => {
return new Promise((resolve, reject) => {
setTimeout(resolve, (seconds * 1000));
});
};
// We are not using `reject` anywhere, but it is good to
// stick to standard signature.
それからこのようにそれを使ってください:
const waitThenDo(howLong, doWhat) => {
return sleep(howLong).then(doWhat);
};
doWhat
関数はnew Promise(...)
内でresolve
コールバックになることに注意してください。
また、これは非同期睡眠です。イベントループをブロックしません。睡眠を遮断する必要がある場合は、C++バインディングを使用して睡眠の遮断を実現するこのライブラリを使用してください。 (非同期環境のようにNodeでスリープをブロックする必要性はまれですが)
これは @ atlex2によって提案されたダーティブロッキングアプローチ に基づくmoment.js風味のモジュールです。 テストにのみ使用してください 。
const moment = require('moment');
let sleep = (secondsToSleep = 1) => {
let sleepUntill = moment().add(secondsToSleep, 'seconds');
while(moment().isBefore(sleepUntill)) { /* block the process */ }
}
module.exports = sleep;
let co = require('co');
const sleep = ms => new Promise(res => setTimeout(res, ms));
co(function*() {
console.log('Welcome to My Console,');
yield sleep(3000);
console.log('Blah blah blah blah extra-blah');
});
上記のこのコードは、Javascriptの非同期コールバックヘル問題を解決したことによる副作用です。これが私がJavascriptをバックエンドの便利な言語にする理由でもあります。実際、これは私の意見では現代のJavaScriptに導入された最もエキサイティングな改善です。それがどのように機能するかを完全に理解するためには、ジェネレータがどのように機能するかについて十分に理解する必要があります。 function
キーワードとそれに続く*
は、現代のJavascriptではジェネレータ関数と呼ばれています。 npmパッケージco
はジェネレータを実行するためのランナー関数を提供しました。
本質的にジェネレーター関数はyield
キーワードを持つ関数の実行を一時停止する方法を提供しました、同時にジェネレーター関数のyield
はジェネレーターの内側と呼び出し側の間で情報を交換することを可能にしました。これにより、呼び出し側が非同期呼び出しからpromise
からデータを抽出し、解決されたデータをジェネレータに返すメカニズムが提供されました。事実上、非同期呼び出しを同期化します。
簡単なのは、何らかのイベントが発生するまで(コード内の別の場所でdone変数がtrueに設定されていることで示される)、または100msごとにタイムアウトがタイムアウトするまで5秒間待つことです。
var timeout=5000; //will wait for 5 seconds or untildone
var scope = this; //bind this to scope variable
(function() {
if (timeout<=0 || scope.done) //timeout expired or done
{
scope.callback();//some function to call after we are done
}
else
{
setTimeout(arguments.callee,100) //call itself again until done
timeout -= 100;
}
})();
何人かの人々にとって、受け入れられた答えはうまくいかなかった、私はこの他の答えを見つけて、それは私のために働いています: どうやったらsetTimeout()コールバックにパラメータを渡せますか?
var hello = "Hello World";
setTimeout(alert, 1000, hello);
'hello'は渡されるパラメータです。タイムアウト時間の経過後にすべてのパラメータを渡すことができます。答えをくれた@Fabio Phmsに感謝します。
Readline-sync( https://www.npmjs.com/package/readline-sync )をご覧ください。
npm install readline-sync
でインストールする
var readlineSync = require('readline-sync');
while(true) {
var input = readlineSync.question("What is your input?");
if(input === 'exit') {
process.exit();
} else {
console.log("Your input was " + input);
}
}
たぶんベストプラクティスではないが、私のために仕事をする
テスト目的で中断するだけの場合は、現在のスレッド実行でこれを試してください。
function longExecFunc(callback, count) {
for (var j = 0; j < count; j++) {
for (var i = 1; i < (1 << 30); i++) {
var q = Math.sqrt(1 << 30);
}
}
callback();
}
longExecFunc(() => { console.log('done!')}, 5); //5, 6 ... whatever. Higher -- longer