Kata pengantar
Sorotan terbesar dari NodeJS adalah model I/O yang digerakkan oleh peristiwa, yang membuat NodeJs memiliki kemampuan pemrosesan konkurensi yang kuat dan sangat cocok untuk menulis aplikasi jaringan. Sebagian besar operasi I/O di NodeJs hampir tidak sinkron, yaitu, hasil operasi I/O kami pada dasarnya perlu diproses dalam fungsi callback, seperti fungsi berikut yang membaca konten file:
Salinan kode adalah sebagai berikut:
fs.readfile ('/etc/passwd', function (err, data) {
if (err) lempar err;
console.log (data);
});
Jadi, apa yang harus kita lakukan jika kita membaca dua file dan menggabungkan konten kedua file ini bersama -sama? Kebanyakan orang yang tidak berhubungan dengan JS dapat melakukan ini:
Salinan kode adalah sebagai berikut:
fs.readfile ('/etc/passwd', function (err, data) {
if (err) lempar err;
fs.readfile ('/etc/passwd2', function (err, data2) {
if (err) lempar err;
// memproses data data dan data2 di sini
});
});
Jika Anda berurusan dengan beberapa skenario serupa, bukankah fungsi panggilan baliknya bersarang lapisan demi lapisan? Inilah yang sering orang sebut kembali piramida atau callback neraka (http://callbackhell.com/), dan itu juga masalah yang paling merepotkan bagi JS novice.
Jenis kode bersarang ini telah membawa banyak masalah pada pengembangan, terutama tercermin dalam:
1. Kemungkinan kode menjadi lebih buruk
2. Kesulitan debugging
3. Sulit untuk memeriksa setelah pengecualian terjadi
Artikel ini terutama memperkenalkan cara menangani masalah panggilan balik asinkron di atas secara elegan.
Solusi utama: memproses callback asinkron secara rekursif
Kita dapat menggunakan rekursi sebagai alat kontrol eksekusi untuk kode. Merangkum operasi yang perlu dieksekusi ke dalam suatu fungsi, dan mengontrol proses eksekusi kode dengan secara rekursif memanggil fungsi callback. Tanpa basa -basi lagi, mari kita bicara tentang omong kosong, mari kita lihat kode sebelumnya:
Salinan kode adalah sebagai berikut:
var fs = membutuhkan ('fs');
// Daftar file yang akan diproses
var file = ['file1', 'file2', 'file3'];
fungsi parsefile () {
if (file.length == 0) {
kembali;
}
var file = file.shift ();
fs.readfile (file, fungsi (err, data) {
// Proses data file di sini
parsefile (); // Setelah diproses, proses file berikutnya melalui panggilan rekursif
});
}
// Mulailah memproses
parsefile ();
Kode di atas telah memproses file dalam array secara bergantian sebagai contoh, memperkenalkan proses eksekusi mengendalikan kode melalui cara rekursif.
Adalah baik untuk menerapkannya pada beberapa skenario sederhana, seperti: kita dapat menggunakan metode ini dengan menyimpan data dalam array ke dalam database secara bergantian.
Secara rekursif, beberapa masalah panggilan balik asinkron sederhana dapat diselesaikan. Namun, tampaknya masih tidak berdaya untuk menangani panggilan balik asinkron yang kompleks (seperti menyinkronkan hasil dari beberapa operasi asinkron).
Poin cantik: Gunakan perpustakaan pihak ketiga seperti Async, Q, berjanji untuk menangani panggilan balik asinkron
Untuk menangani panggilan balik bersarang dengan lebih baik, Anda dapat mempertimbangkan untuk menggunakan beberapa perpustakaan pihak ketiga yang secara khusus berurusan dengan asinkron. Tentu saja, jika Anda memiliki kemampuan, Anda dapat menulis alat tambahan untuk pemrosesan asinkron sendiri.
Perpustakaan yang paling umum digunakan untuk menangani pemrosesan asinkron adalah: async, q dan janji. Dilihat dari situs web npmjs.org, Async adalah yang paling populer. Saya telah menggunakan async sebelumnya, dan memang cukup nyaman, dan berbagai aliran kontrol pemrosesan asinkron diimplementasikan dengan baik.
Kami akan menggunakan async untuk memproses kode yang awalnya membaca dua file secara bersamaan, seperti yang ditunjukkan di bawah ini:
Salinan kode adalah sebagai berikut:
var async = membutuhkan ('async')
, fs = membutuhkan ('fs');
async.parallel ([
function (callback) {
fs.readfile ('/etc/passwd', function (err, data) {
if (err) callback (err);
Callback (null, data);
});
},
function (callback) {
fs.readfile ('/etc/passwd2', function (err, data2) {
if (err) callback (err);
callback (null, data2);
});
}
],
fungsi (err, hasil) {
// memproses data data dan data2 di sini, dan konten setiap file diperoleh dari hasil
});
Melalui modul async, proses eksekusi asinkron dapat dikontrol dengan baik, yang juga dapat menyelesaikan masalah panggilan balik berlapis. Kode lebih jelas dari sebelumnya, tetapi masih tidak dapat dipisahkan dari fungsi callback.
Pikirkan tentang hal ini, akan lebih bagus jika Anda dapat menangani asinkron tanpa menggunakan fungsi callback. Selanjutnya, mari kita bicara tentang menggunakan fitur baru ES6 untuk mencapai tujuan ini.
Titik elegan: Rangkul ES6, ganti fungsi panggilan balik, dan selesaikan masalah neraka panggilan balik
Ngomong -ngomong, Ecmascript Harmony (ES6) telah memperkenalkan banyak fitur baru ke JS. Siswa yang tidak tahu banyak tentang ES6 dapat mengambil tampilan Baidu sendiri.
Untuk menggunakan fitur baru ES6 di NodeJs, Anda perlu menggunakan v0.11.x atau lebih tinggi.
Artikel ini memperkenalkan penggunaan fitur generator alih -alih fungsi panggilan balik. Tidak tahu tentang generator? Anda dapat memeriksanya di sini.
Di sini kami menggunakan dua modul CO dan Thunkify, dan kami menggunakan perintah Install NPM untuk menginstalnya.
Ambil masalah yang disebutkan di awal artikel ini sebagai contoh. Kode contoh menggunakan fitur generator adalah sebagai berikut:
Salinan kode adalah sebagai berikut:
var fs = membutuhkan ('fs')
, co = membutuhkan ('co')
, thunkify = membutuhkan ('thunkify');
var readfile = thunkify (fs.readfile);
co (function *() {
var test1 = hasil readFile ('test1.txt');
var test2 = hasil readFile ('test2.txt');
var test = test1.toString () + test2.toString ();
console.log (tes);
}) ();
Juga sangat sederhana untuk menangani pengecualian dalam kode, lakukan saja dengan cara ini:
Salinan kode adalah sebagai berikut:
mencoba {
var test1 = hasil readFile ('test1.txt');
} catch (e) {
// Tangani pengecualian di sini
}
Apakah kode semacam ini jauh lebih elegan? Bukankah bagus untuk menangani secara tidak sinkron seperti menulis kode sinkron?
Kerangka kerja paling populer untuk pengembangan web di bidang NodeJS adalah ekspres. Perlu disebutkan bahwa anggota inti Express TJ, Great Master of Express, telah memimpin kerangka kerja web baru - KOA, yang mengklaim sebagai generasi berikutnya dari kerangka kerja pengembangan web. KOA benar -benar menggunakan fitur ES6 Generator untuk membantu kita menghindari jatuh ke lapisan callback saat mengembangkan sistem web.
Meringkaskan
Kutipan Kalimat Dari Promosi Proyek FIBJS: Lebih sedikit panggilan balik, lebih banyak gadis - lebih sedikit panggilan balik, lebih banyak gadis