Solusi terakhir Anda adalah satu-satunya yang benar.
Dua solusi lainnya seharusnya tidak bekerja seperti yang Anda harapkan. Sebenarnya, ini akan menghasilkan loop tak terbatas.
Ini karena cara kerja eventloop JavaScript . Gambar berikut menunjukkan model runtime JavaScript (Gambar diambil dari sini ):
Bagian yang relevan bagi kami adalah stack
dan queue
. JavaScript runtime memproses pesan di Internet queue
. Setiap pesan dikaitkan dengan fungsi yang dipanggil saat pesan diproses.
Untuk stack, setiap panggilan fungsi membuat bingkai di stack yang berisi argumen fungsi dan variabel lokal. Jika suatu fungsi memanggil fungsi lain, bingkai baru didorong di atas tumpukan. Ketika suatu fungsi mengembalikan bingkai atas muncul dari tumpukan.
Sekarang jika stack kosong, JavaScript runtime akan memproses pesan berikutnya pada queue
(yang tertua).
Jika Anda menggunakan setTimeout(() => doSomething(),100)
, doSomething()
fungsi akan ditambahkan ke antrian setelah 100 milidetik. Ini adalah alasan mengapa 100 milidetik bukan waktu yang terjamin tetapi waktu yang minimal. Karena itu Anda doSomething method
hanya dipanggil, jika tumpukannya kosong dan tidak ada yang lain dalam antrian.
Tetapi karena Anda mengulangi dalam loop sementara dan kondisi Anda tergantung pada kode di dalam Anda setTimeout
, Anda telah membuat loop tak terbatas karena tumpukan tidak akan kosong dan karena itu this.posts.push(this.postService.next(10));
kode Anda tidak akan pernah dipanggil.
Untuk implementasi RxJS, hal yang sama berlaku. Mereka menggunakan penjadwal untuk menangani waktu. Ada implementasi internal scheduler yang berbeda di RxJS, tetapi seperti yang dapat kita lihat dalam implementasi untuk interval
dan timer
, jika kita tidak menentukan scheduler, defaultnya adalah asyncScheduler. Jadwal asyncScheduler bekerja dengan setInterval
yang berfungsi seperti setTimeout
disebutkan di atas, dan mendorong pesan lain di antrian.
Saya mencoba dua solusi Anda dengan loop sementara dan yang pertama benar-benar membeku browser saya sedangkan yang kedua adalah super laggy tetapi bisa mengeluarkan sesuatu ke konsol di dalam loop sementara. Saya sebenarnya tidak tahu mengapa yang kedua sedikit lebih banyak performan, tetapi keduanya bukan yang sebenarnya Anda inginkan. Anda telah menemukan solusi yang bagus dan saya harap jawaban ini dapat membantu Anda memahami mengapa solusi pertama berkinerja buruk.