Apa itu I / O non-blocking atau asynchronous di Node.js?

138

Dalam konteks mesin Javascript Sisi Server, apa itu I / O non-pemblokiran atau I / O asinkron? Saya melihat ini disebutkan sebagai keuntungan atas implementasi sisi server Java.

Anand
sumber
3
Sangat membantu untuk memikirkan tentang tag skrip di lingkungan browser untuk memahami konsep ini. Zakas punya artikel bagus tentang ini - beberapa bagian pertama seharusnya cukup untuk menjelaskan konsep pemblokiran: nczonline.net/blog/2010/08/10/what-is-a-non-blocking-script
netpoetica

Jawaban:

323

Sinkron vs Asinkron

Eksekusi sinkron biasanya mengacu pada kode yang dijalankan secara berurutan. Eksekusi asinkron mengacu pada eksekusi yang tidak berjalan dalam urutan yang muncul di kode. Dalam contoh berikut, operasi sinkron menyebabkan peringatan diaktifkan secara berurutan. Dalam operasi async, meskipun alert(2)tampaknya mengeksekusi kedua, itu tidak.

Sinkron: 1,2,3

alert(1);
alert(2);
alert(3);

Asinkron: 1,3,2

alert(1);
setTimeout(() => alert(2), 0);
alert(3);

Pemblokiran vs Non-pemblokiran

Pemblokiran mengacu pada operasi yang memblokir eksekusi lebih lanjut hingga operasi tersebut selesai. Non-pemblokiran mengacu pada kode yang tidak memblokir eksekusi. Dalam contoh yang diberikan, localStorageadalah operasi pemblokiran karena menghentikan eksekusi untuk membaca. Di sisi lain, fetchmerupakan operasi non-pemblokiran karena tidak berhenti alert(3)dari eksekusi.

// Blocking: 1,... 2
alert(1);
var value = localStorage.getItem('foo');
alert(2);

// Non-blocking: 1, 3,... 2
alert(1);
fetch('example.com').then(() => alert(2));
alert(3);

Keuntungan

Satu keuntungan dari operasi non-pemblokiran dan asinkron adalah Anda dapat memaksimalkan penggunaan satu CPU serta memori.

Sinkron, contoh pemblokiran

Contoh operasi pemblokiran sinkron adalah bagaimana beberapa server web seperti yang ada di Java atau PHP menangani IO atau permintaan jaringan. Jika kode Anda membaca dari file atau database, kode Anda "memblokir" semuanya setelahnya agar tidak dijalankan. Dalam periode itu, mesin Anda menahan memori dan waktu pemrosesan untuk utas yang tidak melakukan apa pun .

Untuk memenuhi permintaan lain saat utas itu terhenti bergantung pada perangkat lunak Anda. Apa yang dilakukan sebagian besar perangkat lunak server adalah memunculkan lebih banyak utas untuk memenuhi permintaan tambahan. Ini membutuhkan lebih banyak memori yang dikonsumsi dan lebih banyak pemrosesan.

Contoh asinkron, non-pemblokiran

Server asinkron dan non-pemblokiran - seperti yang dibuat di Node - hanya menggunakan satu utas untuk melayani semua permintaan. Ini berarti instance Node memanfaatkan satu utas secara maksimal. Pencipta merancangnya dengan premis bahwa I / O dan operasi jaringan adalah penghambatnya.

Ketika permintaan sampai di server, mereka dilayani satu per satu. Namun, ketika kode yang dilayani perlu meminta DB misalnya, ia mengirim callback ke antrian kedua dan utas utama akan terus berjalan (tidak menunggu). Sekarang ketika operasi DB selesai dan kembali, callback terkait ditarik keluar dari antrian kedua dan mengantri dalam antrian ketiga dimana mereka menunggu eksekusi. Saat mesin mendapat kesempatan untuk mengeksekusi sesuatu yang lain (seperti saat tumpukan eksekusi dikosongkan), mesin mengambil callback dari antrian ketiga dan menjalankannya.

Joseph
sumber
5
Saya tidak yakin saya mengerti paragraf kedua Anda di bawah Pemblokiran di PHP . Apakah Anda mengatakan bahwa, "Meskipun PHP biasanya akan memblokir di IO, itu tidak terjadi karena OS secara otomatis merangkai operasi IO."? Atau, apakah Anda mengatakan bahwa ini bukan masalah di PHP karena PHP secara otomatis membuat utas baru untuk setiap permintaan sehingga satu permintaan yang diblokir tidak menghentikan seluruh lingkungan PHP? (Saya menebak yang terakhir ..)
dcow
6
Itu yang terakhir.
Joseph
2
tunggu, kalau maksudnya yang terakhir, apa kelebihan non blocking I / O PHP (seperti reactPHP atau yang lainnya) dibanding yang memblokir. masih bingung
Sunu Pinasthika Fajar
5
@CarlieYa. Operasi asinkron berjalan paralel dengan kode Anda. Tetapi callback yang "kembali" ke hasil operasi asinkron akan diantrekan untuk dieksekusi dalam kode utama saat kode utama tidak sibuk.
Joseph
2
@CharlieParker Berikut adalah posting yang membahas lebih lanjut tentang internal dari mekanisme async.
Joseph
7
var startTime = new Date().getTime();
var getEndTime = () => {
    var tempEndTime = new Date().getTime();
    var second = (tempEndTime - startTime)/1000
    return `took ${second} sec...to finish\n`
}

console.log('1: start App', getEndTime())
setTimeout(()=>{
    console.log('2: setTimeout', getEndTime())
}, 1000)
console.log('3: End App', getEndTime())

// console -> Process Order:  1 -> 3 -> 2

Contoh kode

Wayne Chiu
sumber