Apa perbedaan antara keduanya, dan kapan saya akan menggunakan salah satunya?
javascript
node.js
Shlomi Schwartz
sumber
sumber
Jawaban:
setTimeout sama seperti memanggil fungsi setelah penundaan selesai. Setiap kali sebuah fungsi dipanggil, itu tidak segera dijalankan, tetapi antri sehingga dijalankan setelah semua eventhandler yang sedang dieksekusi dan antri selesai terlebih dahulu. setTimeout (, 0) pada dasarnya berarti mengeksekusi setelah semua fungsi saat ini dalam antrian saat ini dijalankan. Tidak ada jaminan tentang berapa lama waktu yang dibutuhkan.
setImmediate serupa dalam hal ini kecuali bahwa ia tidak menggunakan antrian fungsi. Ia memeriksa antrian eventhandler I / O. Jika semua kejadian I / O dalam snapshot saat ini diproses, callback akan dijalankan. Ini mengantri mereka segera setelah penangan I / O terakhir agak seperti proses.nextTick. Jadi lebih cepat.
Juga (setTimeout, 0) akan lambat karena akan memeriksa pengatur waktu setidaknya sekali sebelum dijalankan. Kadang-kadang bisa dua kali lebih lambat. Ini patokannya.
var Suite = require('benchmark').Suite var fs = require('fs') var suite = new Suite suite.add('deffered.resolve()', function(deferred) { deferred.resolve() }, {defer: true}) suite.add('setImmediate()', function(deferred) { setImmediate(function() { deferred.resolve() }) }, {defer: true}) suite.add('setTimeout(,0)', function(deferred) { setTimeout(function() { deferred.resolve() },0) }, {defer: true}) suite .on('cycle', function(event) { console.log(String(event.target)); }) .on('complete', function() { console.log('Fastest is ' + this.filter('fastest').pluck('name')); }) .run({async: true})
Keluaran
deffered.resolve() x 993 ops/sec ±0.67% (22 runs sampled) setImmediate() x 914 ops/sec ±2.48% (57 runs sampled) setTimeout(,0) x 445 ops/sec ±2.79% (82 runs sampled)
Yang pertama memberikan ide tentang panggilan tercepat. Anda dapat memeriksa diri Anda sendiri jika setTimeout dipanggil setengah kali dari yang lain. Ingat juga setImmediate akan menyesuaikan dengan panggilan sistem file Anda. Jadi di bawah beban itu akan bekerja lebih sedikit. Saya tidak berpikir setTimeout bisa bekerja lebih baik.
setTimeout adalah cara memanggil fungsi yang tidak mengganggu setelah beberapa waktu. Ini seperti di browser. Ini mungkin tidak cocok untuk sisi server (pikirkan mengapa saya menggunakan benchmark.js bukan setTimeout).
sumber
Artikel bagus tentang cara kerja event loop dan menghapus beberapa kesalahpahaman. http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/
Mengutip artikel:
setImmediate
callback dipanggil setelah I / O Queue callbacks selesai atau waktunya habis. setImmediate callbacks ditempatkan di Check Queue, yang diproses setelah I / O Queue.setTimeout(fn, 0)
callback ditempatkan di Timer Queue dan akan dipanggil setelah callback I / O serta callback Check Queue. Sebagai loop peristiwa, proses antrian pengatur waktu terlebih dahulu di setiap iterasi, sehingga mana yang akan dieksekusi terlebih dahulu tergantung pada loop peristiwa fase mana.sumber
setImmediate () adalah untuk menjadwalkan eksekusi callback segera setelah kejadian I / O callback dan sebelum setTimeout dan setInterval.
setTimeout () adalah untuk menjadwalkan eksekusi callback satu kali setelah penundaan milidetik.
Inilah yang tertulis dalam dokumen.
setTimeout(function() { console.log('setTimeout') }, 0) setImmediate(function() { console.log('setImmediate') })
Jika Anda menjalankan kode di atas, hasilnya akan seperti ini ... meskipun dokumen saat ini menyatakan bahwa "Untuk menjadwalkan eksekusi callback" langsung "setelah kejadian I / O callback dan sebelum setTimeout dan setInterval." ..
Hasil..
Jika Anda menggabungkan contoh Anda di timer lain, itu selalu mencetak setImmediate diikuti oleh setTimeout.
setTimeout(function() { setTimeout(function() { console.log('setTimeout') }, 0); setImmediate(function() { console.log('setImmediate') }); }, 10);
sumber
selalu gunakan
setImmediate
, kecuali jika Anda benar-benar yakin bahwa Anda membutuhkannyasetTimeout(,0)
(tetapi saya bahkan tidak dapat membayangkan, untuk apa).setImmediate
callback akan hampir selalu dijalankan sebelumnyasetTimeout(,0)
, kecuali saat dipanggil di tik pertama dan disetImmediate
callback.sumber
setTimeout
harus menjadi tujuan, dengansetImmediate
digunakan hanya jika terbukti perlu.Benar-benar tidak puas dengan jawaban yang diberikan. Saya memposting apa yang menurut saya merupakan jawaban yang lebih baik di sini: https://stackoverflow.com/a/56724489/5992714
Pertanyaan adalah kemungkinan duplikat dari Mengapa perilaku setTimeout (0) dan setImmediate () tidak ditentukan ketika digunakan dalam modul utama?
sumber
Saya rasa jawaban Navya S tidak benar, berikut kode tes saya:
let set = new Set(); function orderTest() { let seq = []; let add = () => set.add(seq.join()); setTimeout(function () { setTimeout(function () { seq.push('setTimeout'); if (seq.length === 2) add(); }, 0); setImmediate(function () { seq.push('setImmediate'); if (seq.length === 2) add(); }); }, 10); } // loop 100 times for (let i = 0; i < 100; i++) { orderTest(); } setTimeout(() => { // will print one or two items, it's random for (item of set) { console.log(item); } }, 100);
Penjelasannya ada di sini
sumber
setTimeout (fn, 0) dapat digunakan untuk mencegah browser membeku dalam pembaruan besar-besaran. misalnya di websocket.onmessage, Anda mungkin memiliki perubahan html, dan jika pesan terus datang, browser mungkin berhenti saat menggunakan setImmidiate
sumber
Untuk memahaminya secara mendalam, harap sekali melalui fase loop peristiwa.
SetImmediate: Ini dijalankan pada fase "check". The cek fase disebut setelah fase I / O.
SetTimeOut: Ini dijalankan dalam fase "timer". The Timer fase adalah tahap pertama tetapi disebut setelah I / O fase serta Periksa fase.
Untuk mendapatkan keluaran secara deterministik, itu akan tergantung pada fase mana loop-peristiwa itu berada; karenanya, kita dapat menggunakan fungsi dari dua fungsi tersebut.
sumber
gunakan setImmediate () untuk tidak memblokir event loop. Callback akan berjalan pada loop acara berikutnya, segera setelah yang sekarang selesai.
gunakan setTimeout () untuk penundaan terkontrol. Fungsi akan berjalan setelah penundaan yang ditentukan. Penundaan minimum adalah 1 milidetik.
sumber