Jika Anda terbiasa dengan pemrograman JavaScript sisi klien, Anda mungkin telah menggunakan fungsi setTimeout dan setInterval, yang memungkinkan penundaan untuk periode waktu sebelum menjalankan fungsi. Misalnya, kode berikut, setelah dimuat di halaman web, setelah 1 detik, "halo di sana" akan ditambahkan setelah dokumen halaman:
Salinan kode adalah sebagai berikut:
var onesecond = 1000 * 1; // satu detik = 1000 x 1 ms
setTimeout (function () {
document.write ('<p> halo disana. </p>');
}, OneSecond);
dan SetInterval memungkinkan pelaksanaan fungsi berulang pada interval waktu yang ditentukan. Jika kode berikut disuntikkan ke halaman web, itu akan menyebabkan kalimat berikut "halo di sana" ditambahkan ke dokumen halaman setiap detik:
Salinan kode adalah sebagai berikut:
var onesecond = 1000 * 1; // satu detik = 1000 x 1 ms
setInterval (function () {
document.write ('<p> halo disana. </p>');
}, OneSecond);
Karena web telah lama menjadi platform untuk membangun aplikasi, bukan halaman statis sederhana, permintaan serupa ini semakin muncul. Fungsi perencanaan tugas ini membantu pengembang menerapkan verifikasi formulir secara berkala, menunda sinkronisasi data jarak jauh, atau interaksi UI yang memerlukan respons tertunda. Node juga mengimplementasikan metode ini secara penuh. Di sisi server, Anda dapat menggunakannya untuk mengulangi atau menunda eksekusi banyak tugas, seperti kadaluwarsa cache, pembersihan kolam koneksi, kedaluwarsa sesi, pemungutan suara, dan banyak lagi.
Jalankan menggunakan fungsi penundaan setTimeout
SetTimeout dapat membuat rencana eksekusi yang menjalankan fungsi yang ditentukan sekali pada waktu tertentu di masa depan, seperti:
Salinan kode adalah sebagai berikut:
var timeout_ms = 2000; // 2 detik
var timeout = setTimeout (function () {
console.log ("Timeed Out!");
}, timeout_ms);
Seperti JavaScript klien, SetTimeout menerima dua parameter. Parameter pertama adalah fungsi yang perlu ditunda, dan parameter kedua adalah waktu tunda (dalam milidetik).
SetTimeout Mengembalikan pegangan batas waktu, yang merupakan objek internal. Anda dapat menggunakannya sebagai parameter untuk menghubungi ClearTimeout untuk membatalkan timer. Kecuali itu, pegangan ini tidak berpengaruh.
Gunakan ClearTimeout untuk membatalkan rencana eksekusi
Setelah pegangan batas waktu diperoleh, Anda dapat menggunakan ClearTimeout untuk membatalkan rencana eksekusi fungsi, seperti ini:
Salinan kode adalah sebagai berikut:
var timeouttime = 1000; // satu detik
var timeout = setTimeout (function () {
console.log ("Timeed Out!");
}, timeouttime);
ClearTimeout (timeout);
Dalam contoh ini, timer tidak akan pernah dipicu dan tidak akan menghasilkan kata -kata "Time Out!". Anda juga dapat membatalkan rencana eksekusi kapan saja di masa depan, seperti contoh berikut:
Salinan kode adalah sebagai berikut:
var timeout = setTimeOut (function a () {
console.log ("Timeed Out!");
}, 2000);
setTimeout (fungsi b () {
ClearTimeout (timeout);
}, 1000);
Kode ini menentukan dua fungsi A dan B yang dieksekusi tertunda. Fungsi A direncanakan untuk dieksekusi setelah 2 detik, dan B direncanakan untuk dieksekusi setelah 1 detik, karena fungsi B dieksekusi terlebih dahulu, dan itu membatalkan rencana eksekusi A, sehingga A tidak akan pernah berjalan.
Mengembangkan dan membatalkan rencana eksekusi fungsi yang berulang
SetInterval mirip dengan SetTimeout, tetapi akan berulang kali menjalankan fungsi pada interval waktu yang ditentukan. Anda dapat menggunakannya untuk secara berkala memicu program untuk menyelesaikan beberapa tugas lain yang perlu diulang, seperti membersihkan, mengumpulkan, logging, mendapatkan data, pemungutan suara, dll.
Kode berikut akan menghasilkan "centang" ke konsol setiap detik:
Salinan kode adalah sebagai berikut:
periode var = 1000; // 1 detik
setInterval (function () {
console.log ("centang");
}, periode);
Jika Anda tidak ingin berjalan selamanya, Anda dapat menggunakan ClearInterval () untuk membatalkan timer.
SetInterval Mengembalikan Pegangan Rencana Eksekusi, yang dapat digunakan sebagai parameter untuk menghapus interval untuk membatalkan Rencana Eksekusi:
Salinan kode adalah sebagai berikut:
var interval = setInterval (function () {
console.log ("centang");
}, 1000);
//…
ClearInterval (Interval);
Gunakan proses.nexttick untuk menunda eksekusi fungsi ke putaran berikutnya dari loop acara
Terkadang programmer JavaScript klien menggunakan SetTimeout (Callback, 0) untuk menunda tugas untuk jangka waktu singkat. Parameter kedua adalah 0 milidetik. Ini memberitahu JavaScript untuk menjalankan fungsi panggilan balik ini segera setelah semua acara yang tertunda diproses. Terkadang teknik ini digunakan untuk menunda pelaksanaan operasi yang tidak perlu dilakukan segera. Misalnya, kadang -kadang Anda perlu mulai bermain animasi atau melakukan beberapa perhitungan lain setelah acara pengguna diproses.
Di Node, sama seperti makna literal "Loop Acara", loop acara berjalan dalam loop yang menangani antrian acara, dan setiap putaran dalam pekerjaan loop acara disebut Tick.
Anda dapat memanggil fungsi callback sekali setiap kali loop acara memulai eksekusi putaran berikutnya (kutu berikutnya), yang persis prinsip proses.
Dengan menggunakan proses.nexttick (callback) alih -alih setTimeout (callback, 0), fungsi callback Anda akan dieksekusi segera setelah acara dalam antrian diproses. Ini jauh lebih cepat daripada antrian batas waktu JavaScript (diukur dengan waktu CPU).
Anda dapat menunda fungsi sampai loop acara berikutnya dan menjalankannya seperti ini:
Salinan kode adalah sebagai berikut:
process.nexttick (function () {
my_expensive_computation_function ();
});
Catatan: Objek proses adalah salah satu dari sedikit objek global di Node.
Loop acara pemblokiran
Runtime Node dan JavaScript menggunakan loop acara tunggal. Setiap loop, runtime menggunakan fungsi callback untuk menangani acara berikutnya dalam antrian. Ketika acara dieksekusi, loop acara memperoleh hasil eksekusi dan memproses acara berikutnya, mengulanginya sampai antrian acara kosong. Jika salah satu panggilan balik membutuhkan waktu lama untuk dijalankan, loop acara tidak dapat menangani acara lainnya yang tertunda selama waktu itu, yang dapat membuat aplikasi atau layanan sangat lambat.
Saat memproses peristiwa, jika fungsi sensitif-memori atau sensitif prosesor digunakan, loop peristiwa akan menjadi lambat, dan sejumlah besar peristiwa akan menumpuk, yang tidak dapat diproses dalam waktu, atau bahkan memblokir antrian.
Lihat contoh loop acara pemblokiran berikut:
Salinan kode adalah sebagai berikut:
process.nexttick (function nextTick1 () {
var a = 0;
while (true) {
a ++;
}
});
Process.nextTick (function nextTick2 () {
Console.log ("Tick Next");
});
setTimeout (function timeout () {
console.log ("timeout");
}, 1000);
Dalam contoh ini, fungsi NextTick2 dan Timeout tidak memiliki kesempatan untuk berlari tidak peduli berapa lama mereka menunggu, karena loop acara diblokir oleh loop tak terbatas dalam fungsi NextTick, dan itu tidak akan berjalan bahkan jika fungsi waktu tunggu dijadwalkan untuk dieksekusi setelah 1 detik.
Ketika SetTimeout digunakan, fungsi callback ditambahkan ke antrian rencana eksekusi, dan dalam hal ini mereka bahkan tidak ditambahkan ke antrian. Meskipun ini adalah contoh ekstrem, Anda dapat melihat bahwa menjalankan tugas yang peka terhadap prosesor dapat memblokir atau memperlambat loop peristiwa.
Keluar dari Loop Acara
Menggunakan Process.nexttick, tugas non-kritis dapat ditunda ke putaran berikutnya dari Loop Event (Tick) sebelum dieksekusi, yang dapat membebaskan Loop Acara sehingga dapat terus melaksanakan acara yang tertunda lainnya.
Lihat contoh berikut. Jika Anda berencana untuk menghapus file sementara tetapi tidak ingin fungsi panggilan balik dari acara data untuk menunggu operasi IO ini, Anda dapat menunda seperti ini:
Salinan kode adalah sebagai berikut:
stream.on ("data", fungsi (data) {
stream.end ("respons saya");
process.nexttick (function () {
fs.unlink ("/path/to/file");
});
});
Gunakan SetTimeout alih -alih SetInterval untuk memastikan serialitas eksekusi fungsi
Misalkan Anda berencana untuk merancang fungsi yang disebut my_async_function, yang dapat melakukan beberapa operasi I/O (seperti penguraian file log) dan bermaksud untuk membuatnya dieksekusi secara berkala. Anda dapat mengimplementasikannya dengan SetInterval seperti ini:
Salinan kode adalah sebagai berikut:
var interval = 1000;
setInterval (function () {
my_async_function (function () {
console.log ('my_async_function selesai!');
});
}, interval); // Catatan penerjemah: Saya menambahkan "interval" sebelumnya dan penulis seharusnya melewatkannya karena kesalahan ketik
Anda harus dapat memastikan bahwa fungsi -fungsi ini tidak dieksekusi secara bersamaan, tetapi jika Anda menggunakan SetInterval, Anda tidak dapat menjamin ini. Jika fungsi my_async_function berjalan satu milidetik lebih lama dari variabel interval, mereka akan dieksekusi secara bersamaan, daripada serial secara berurutan.
Catatan Penerjemah: (Bagian tebal di bawah ini ditambahkan oleh penerjemah, bukan konten dari buku asli)
Untuk memfasilitasi pemahaman tentang bagian konten ini, Anda dapat memodifikasi kode penulis sehingga dapat benar -benar berjalan:
Salinan kode adalah sebagai berikut:
var interval = 1000;
setInterval (function () {
(function my_async_function () {
setTimeout (function () {
console.log ("1");
}, 5000);
}) ();
},selang);
Jalankan kode ini dan Anda akan menemukan bahwa setelah menunggu 5 detik, "halo" adalah output setiap 1 detik. Kami berharap bahwa setelah my_async_function saat ini telah dieksekusi (diambil 5 detik), tunggu 1 detik sebelum menjalankan my_async_function berikutnya, dan interval antara setiap output harus 6 detik. Hasil ini karena my_async_function tidak dieksekusi secara serial, tetapi dijalankan pada saat yang sama.
Oleh karena itu, Anda memerlukan cara untuk memaksa interval antara akhir eksekusi my_async_function dan awal eksekusi my_async_function berikutnya adalah persis waktu yang ditentukan oleh variabel interval. Anda dapat melakukan ini:
Salinan kode adalah sebagai berikut:
var interval = 1000; // 1 detik
(function jadwal () {// baris 3
setTimeout (function do_it () {
my_async_function (function () {// baris 5
console.log ('async sudah selesai!');
jadwal();
});
}, interval);
} ()); // baris 10
Dalam kode sebelumnya, fungsi yang disebut jadwal (baris 3) dinyatakan, dan dipanggil segera setelah deklarasi (baris 10). Fungsi jadwal akan menjalankan fungsi do_it setelah 1 detik (ditentukan berdasarkan interval). Setelah 1 detik, fungsi my_async_function pada baris 5 akan dipanggil. Ketika dieksekusi, ia akan memanggil fungsi panggilan balik anonimnya sendiri (baris 6). Fungsi panggilan balik anonim ini akan mengatur ulang rencana eksekusi DO_IT lagi dan membiarkannya dieksekusi lagi setelah 1 detik, sehingga kode akan mulai dieksekusi secara serial dan terus menerus.
ringkasan
Anda dapat menggunakan fungsi setTimeout () untuk mempreset rencana eksekusi fungsi dan membatalkannya dengan fungsi clearTimeout (). Anda juga dapat menggunakan setInterval () untuk menjalankan fungsi tertentu berulang kali secara berkala. Dengan demikian, Anda dapat menggunakan ClearInterVal () untuk membatalkan rencana eksekusi berulang ini.
Jika loop acara diblokir dengan menggunakan operasi yang sensitif terhadap prosesor, fungsi yang awalnya direncanakan akan dieksekusi akan ditunda dan tidak akan pernah dieksekusi. Jadi jangan gunakan operasi sensitif CPU dalam loop acara. Juga, Anda dapat menggunakan proses.nextTick () untuk menunda pelaksanaan fungsi hingga putaran berikutnya dari loop acara.
Saat menggunakan I/O dan setInterval () bersama -sama, Anda tidak dapat menjamin bahwa hanya ada satu panggilan yang tertunda pada titik waktu mana pun, tetapi Anda dapat menggunakan fungsi rekursif dan fungsi setTimeout () untuk menghindari masalah rumit ini.