Saya sedang mengembangkan konsol seperti naskah untuk kebutuhan pribadi. Saya harus dapat berhenti untuk waktu yang lama, tetapi, dari penelitian saya, node.js tidak memiliki cara untuk berhenti seperti yang diperlukan. Semakin sulit membaca informasi pengguna setelah jangka waktu tertentu ... Saya telah melihat beberapa kode di luar sana, tetapi saya percaya mereka harus memiliki kode lain di dalamnya agar mereka dapat bekerja seperti:
setTimeout(function() {
}, 3000);
Namun, saya perlu segalanya setelah baris kode ini untuk dieksekusi setelah periode waktu.
Sebagai contoh,
//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.
Saya juga pernah melihat hal-hal seperti
yield sleep(2000);
Tetapi node.js tidak mengenali ini.
Bagaimana saya bisa mencapai jeda yang diperpanjang ini?
javascript
node.js
yield
Christopher Allen
sumber
sumber
require("child_process").execSync('php -r "sleep($argv[1]);" ' + seconds);
Jawaban:
Cara terbaik untuk melakukannya adalah dengan memecah kode Anda menjadi beberapa fungsi, seperti ini:
Ini mirip dengan solusi JohnnyHK , tetapi jauh lebih rapi dan lebih mudah diperluas.
sumber
debugger;
Jawaban baru untuk pertanyaan lama. Hari ini (
Jan 2017Juni 2019) jauh lebih mudah. Anda dapat menggunakan sintaks baruasync/await
. Sebagai contoh:Untuk menggunakan diasync/await
luar kotak tanpa menginstal dan plugin, Anda harus menggunakan node-v7 atau node-v8, menggunakan--harmony
flag.Pembaruan Juni 2019: Dengan menggunakan versi terbaru NodeJS Anda dapat menggunakannya di luar kotak. Tidak perlu memberikan argumen baris perintah. Bahkan Google Chrome mendukungnya hari ini.
Pembaruan Mei 2020: Anda akan segera dapat menggunakan
await
sintaks di luar fungsi async. Di tingkat atas seperti dalam contoh iniProposal ada di tahap 3 . Anda dapat menggunakannya hari ini dengan menggunakan webpack 5 (alpha),
Info lebih lanjut:
sumber
await
kata kunci di depansleep(1000)
let sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
Untuk orang aneh seperti saya :)let sleep = require('util').promisify(setTimeout);
bekerja pada Node 7.6+ dan meningkatkan keterbacaanSolusi terpendek tanpa ketergantungan:
sumber
let sleep = require('util').promisify(setTimeout);
tiga karakter lebih panjang tetapi dapat digunakan kembali dan lebih mudah dibacaresolve
bukandone
. Yaituawait new Promise(resolve => setTimeout(resolve, 5000))
Masukkan kode yang ingin Anda jalankan setelah penundaan dalam
setTimeout
panggilan balik:sumber
node-fibers
. Coba lihat.Ini adalah teknik pemblokiran sederhana:
Ini memblokir sejauh tidak ada hal lain yang akan terjadi dalam skrip Anda (seperti panggilan balik). Tetapi karena ini adalah skrip konsol, mungkin itu yang Anda butuhkan!
sumber
wait
, itu menghalangi dan berfungsi untuk beberapa tujuan pengujian. Persis apa yang saya cari.spin-wait
.Pada Node 7.6.0 atau lebih tinggi
Node mendukung menunggu secara asli:
maka jika Anda dapat menggunakan fungsi async:
atau:
Pada versi Node yang lebih lama (jawaban asli)
Saya ingin tidur asinkron yang bekerja di Windows & Linux, tanpa memonopoli CPU saya dengan loop yang lama. Saya mencoba paket tidur tetapi tidak mau menginstal di kotak Windows saya. Saya akhirnya menggunakan:
https://www.npmjs.com/package/system-sleep
Untuk menginstalnya, ketik:
Dalam kode Anda,
Bekerja seperti pesona.
sumber
Fungsi tidur sederhana dan elegan menggunakan Javascript modern
Tidak ada ketergantungan, tidak ada panggilan balik neraka; itu dia :-)
Mempertimbangkan contoh yang diberikan dalam pertanyaan, ini adalah bagaimana kita akan tidur di antara dua log konsol:
"Kelemahan" adalah bahwa fungsi utama Anda sekarang juga harus
async
. Tapi, mengingat Anda sudah menulis kode Javascript modern, Anda mungkin (atau setidaknya seharusnya!) Menggunakanasync
/await
seluruh kode Anda, jadi ini benar-benar bukan masalah. Semua browser modern saat ini mendukungnya .Memberikan sedikit wawasan tentang
sleep
fungsi bagi mereka yang tidak terbiasaasync/await
dan operator panah gemuk, ini adalah cara tertulis untuk menuliskannya:Namun, menggunakan operator panah gemuk membuatnya lebih kecil (dan lebih elegan).
sumber
async
dan membiarkan yang lainnya tetap sama. Mungkin lebih jelas dengan ituasync
.async
. Sunting jawaban saya dengan saran Anda. Saya tidak berpikir itu membuat kode lebih jelas; untuk itu, saya akan menggunakan JSDoc saja.const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
Anda dapat menggunakan www.npmjs.com/package/sleep ini
sumber
MacOS
, tetapi mengalami kesalahanCentOS
karena kesalahan node_gyp . Sepertinya tidak portabel.Pertanyaan ini cukup lama, tetapi baru-baru ini V8 telah menambahkan Generator yang dapat memenuhi apa yang diminta OP. Generator umumnya paling mudah digunakan untuk interaksi async dengan bantuan perpustakaan seperti suspend atau gen-run .
Berikut ini contoh menggunakan penangguhan:
Bacaan terkait (dengan cara mempromosikan diri yang tidak tahu malu): Apa Kesepakatan Besar dengan Generator? .
sumber
yield setTimeout(suspend.resume(), 10000);
--harmony
bendera, dan menurut node.green, mereka setidaknya tersedia tanpa bendera sejak v4.8.4: node.green/#ES2015-functions-generators-basic-functionality . Harap dicatat, bagaimanapun, bahwaasync/await
sintaks yang lebih baru menyediakan solusi yang lebih baik untuk ini sekarang, tanpa perlu perpustakaan tambahan sepertisuspend
. Lihat jawaban ini untuk contoh: stackoverflow.com/a/41957152/376789 . Fungsi Async tersedia (tanpa flag) sejak v7.10.Di Linux / nodejs ini berfungsi untuk saya:
Itu memblokir, tetapi itu bukan loop menunggu yang sibuk.
Waktu yang Anda tentukan adalah dalam detik tetapi bisa berupa pecahan. Saya tidak tahu apakah OS lain memiliki perintah serupa.
sumber
sleep
cukup banyak hadir dan berada di sekeliling sejak awal UNIX hari en.wikipedia.org/wiki/Sleep_%28Unix%29 . Hanya "tidak jarang" dari itu mungkin tidak ada adalah windows (namun di sana Anda dapat mencobachild_process.spawnSync('timeout', ['/T', '10'])
Jika Anda ingin "golf kode", Anda dapat membuat versi pendek dari beberapa jawaban lain di sini:
Tapi sebenarnya jawaban ideal menurut saya adalah menggunakan
util
perpustakaan Node danpromisify
fungsinya, yang dirancang untuk hal semacam ini (membuat versi berbasis janji dari hal-hal yang sebelumnya tidak berbasis janji):Dalam kedua kasus tersebut, Anda dapat menjeda hanya dengan menggunakan
await
untuk memanggilsleep
fungsi Anda :sumber
await
. Ini semacam membuat panggilan balik, menjeda beberapa hal, dan kemudian me-restart kode ketika panggilan balik itu kembali. Callback kembali dengan nilai, tetapi kami tidak peduli dalam hal ini, jadi tidak ada apa-apa di sebelah kiriawait
.Saya baru-baru ini membuat abstraksi sederhana bernama wait.for untuk memanggil fungsi-fungsi async dalam mode sinkronisasi (berdasarkan pada node-fiber). Ada juga versi berdasarkan ES6 Generator yang akan datang.
https://github.com/luciotato/waitfor
Menggunakan wait.for , Anda dapat memanggil fungsi async nodejs standar apa saja, seolah-olah itu adalah fungsi sinkronisasi, tanpa memblokir loop peristiwa simpul.
Anda dapat kode secara berurutan saat Anda membutuhkannya, yaitu, (saya kira) sempurna untuk menyederhanakan skrip Anda untuk penggunaan pribadi.
menggunakan wait.for kode Anda akan:
Fungsi async apa pun dapat dipanggil dalam mode Sinkronisasi . Lihat contohnya.
sumber
TypeError: Object #<Object> has no method 'miliseconds'
wait.for/paralell-tests.js
saya menemukan kesalahan lain yang berkaitan dengan properti yang tidak ditentukan dll. Jadi saya perlu menyalinnya juga. Mengapa Anda tidak mengatur kode sedemikian rupa sehingga ini tidak diperlukan?Karena, mesin javascript (v8) menjalankan kode berdasarkan urutan peristiwa dalam antrian-acara, Tidak ada batasan ketat bahwa javascript memicu eksekusi tepat setelah waktu yang ditentukan. Yaitu, ketika Anda menetapkan beberapa detik untuk mengeksekusi kode nanti, memicu kode murni berdasarkan urutan dalam antrian acara. Jadi memicu eksekusi kode mungkin membutuhkan waktu lebih dari waktu yang ditentukan.
Jadi Node.js mengikuti,
untuk menjalankan kode nanti, alih-alih setTimeout (). Sebagai contoh,
sumber
Dengan dukungan ES6
Promise
, kita dapat menggunakannya tanpa bantuan pihak ketiga.Kemudian gunakan seperti ini:
Perhatikan bahwa
doWhat
fungsi menjadiresolve
panggilan balik di dalamnew Promise(...)
.Perhatikan juga bahwa ini adalah tidur ASYNCHRONOUS. Itu tidak memblokir loop acara. Jika Anda perlu memblokir tidur, gunakan perpustakaan ini yang menyadari memblokir tidur dengan bantuan binding C ++. (Meskipun kebutuhan untuk memblokir tidur di Node seperti lingkungan async jarang terjadi.)
https://github.com/erikdubbelboer/node-sleep
sumber
Kode di atas adalah efek samping dari penyelesaian masalah neraka panggilan balik asinkron Javascript. Ini juga alasan saya berpikir bahwa menjadikan Javascript bahasa yang berguna di backend. Sebenarnya ini adalah peningkatan paling menarik yang diperkenalkan ke Javascript modern menurut saya. Untuk sepenuhnya memahami cara kerjanya, bagaimana generator bekerja harus dipahami sepenuhnya. Kata
function
kunci yang diikuti oleh*
disebut fungsi generator dalam Javascript modern. Paket npmco
menyediakan fungsi pelari untuk menjalankan generator.Pada dasarnya fungsi generator menyediakan cara untuk menghentikan eksekusi fungsi dengan
yield
kata kunci, pada saat yang sama,yield
dalam fungsi generator memungkinkan untuk bertukar informasi antara di dalam generator dan pemanggil. Ini menyediakan mekanisme bagi pemanggil untuk mengekstrak data daripromise
panggilan asinkron dan untuk meneruskan data yang diselesaikan ke generator. Secara efektif, itu membuat panggilan tidak sinkron sinkron.sumber
Ini adalah modul rasa moment.js berdasarkan pendekatan pemblokiran kotor yang disarankan oleh @ atlex2 . Gunakan ini hanya untuk pengujian .
sumber
Jika Anda hanya perlu menangguhkan untuk tujuan pengujian, eksekusi utas Anda saat ini coba ini:
sumber
sederhana kita akan menunggu 5 detik untuk beberapa peristiwa terjadi (yang akan ditunjukkan oleh variabel yang disetel ke true di tempat lain dalam kode) atau ketika batas waktu habis bahwa kita akan memeriksa setiap 100 ms
sumber
Bagi sebagian orang, jawaban yang diterima tidak berfungsi, saya menemukan jawaban yang lain dan ini berfungsi untuk saya: Bagaimana saya bisa meneruskan parameter ke callback setTimeout ()?
'halo' adalah parameter yang dilewati, Anda dapat melewati semua parameter setelah batas waktu. Terima kasih kepada @Fabio Phms untuk jawabannya.
sumber
Daripada melakukan semua setTimeout ini, tidur dan banyak hal lainnya, lebih baik digunakan
sumber
Jawaban lainnya bagus, tetapi saya pikir saya akan mengambil kebijaksanaan yang berbeda.
Jika yang benar-benar Anda cari adalah memperlambat file tertentu di linux:
node myprog slowfile
Ini akan tidur 1 detik setiap lima baris. Program simpul akan berjalan lambat seperti penulis. Jika melakukan hal lain, mereka akan melanjutkan dengan kecepatan normal.
Mkfifo menciptakan pipa pertama-masuk-pertama-keluar. Inilah yang membuat ini bekerja. Baris perl akan menulis secepat yang Anda inginkan. $ | = 1 mengatakan jangan buffer output.
sumber
Saya mengumpulkan, setelah membaca jawaban dalam pertanyaan ini, fungsi sederhana yang juga dapat melakukan panggilan balik, jika Anda membutuhkannya:
sumber
Untuk info lebih lanjut
Anda harus memeriksa Redux-Saga . Tapi itu khusus untuk pilihan Anda Redux sebagai kerangka kerja model Anda (meskipun sangat tidak perlu).
sumber