Selama proses penulisan node.js, operasi IO berkelanjutan dapat menyebabkan "mimpi buruk piramida". Berbagai sarang fungsi callback membuat kode sulit dipelihara. Janji CommonJS digunakan untuk merangkum fungsi asinkron dan menggunakan API rantai terpadu untuk menyingkirkan mimpi buruk beberapa panggilan balik.
Model IO non-pemblokiran yang disediakan oleh Node.js memungkinkan kami untuk menggunakan fungsi panggilan balik untuk menangani operasi IO, tetapi ketika operasi IO yang berkelanjutan diperlukan, fungsi panggilan balik Anda akan bersarang beberapa kali, kodenya tidak indah, dan tidak mudah dipelihara, dan mungkin ada banyak kode yang diulangi untuk penanganan kesalahan, yang merupakan piramid yang sama ".
Salinan kode adalah sebagai berikut:
Step1 (function (value1) {
Step2 (value1, function (value2) {
Langkah3 (value2, function (value3) {
Step4 (value3, function (value4) {
// Lakukan sesuatu dengan nilai4
});
});
});
});
Ini sebenarnya masalah aliran kontrol di node.js. Ada banyak solusi untuk masalah ini, seperti menggunakan async, eventproxy, dll. Namun, topik artikel ini adalah menggunakan janji dalam spesifikasi CommonJS untuk menyelesaikan masalah ini.
Apa itu janji?
Ada banyak jenis spesifikasi janji untuk umum. Kami biasanya membahas spesifikasi janji/A+, yang mendefinisikan perilaku dasar janji.
Janji adalah objek yang biasanya mewakili operasi asinkron yang dapat diselesaikan di masa depan. Operasi ini mungkin berhasil atau gagal, sehingga objek janji umumnya memiliki 3 negara: tertunda, terpenuhi, dan ditolak. Ini masing -masing mewakili kegagalan penyelesaian dan operasi yang berhasil. Setelah keadaan objek janji berubah dari tertunda menjadi terpenuhi atau ditolak, negaranya tidak dapat diubah lagi.
Objek janji biasanya memiliki metode kemudian, yang memungkinkan kita untuk mengoperasikan nilai yang dikembalikan setelah kemungkinan keberhasilan di masa depan atau alasan kegagalan. Metode ini terlihat seperti ini:
janji.
Jelas bahwa metode kemudian menerima dua parameter, yang biasanya dua fungsi, satu digunakan untuk memproses hasil setelah operasi berhasil, dan yang lainnya digunakan untuk memproses penyebab kegagalan operasi. Parameter pertama dari kedua fungsi ini adalah hasilnya setelah keberhasilan dan penyebab kegagalan. Jika metode itu bukan fungsi, maka parameter ini akan diabaikan.
Nilai pengembalian metode kemudian adalah objek janji, yang memungkinkan kita untuk rantai panggilan kemudian untuk mencapai efek mengendalikan proses. Ada banyak detail di sini, seperti transfer nilai atau penanganan kesalahan. Spesifikasi janji didefinisikan seperti ini:
Nilai pengembalian dari fungsi yang dipenuhi atau dilaporkan bukan objek janji, maka nilainya akan digunakan sebagai parameter pertama dari onfulfilled dalam metode berikutnya. Jika nilai pengembalian adalah objek janji, bagaimana nilai pengembalian metode maka menjadi objek janji
Jika pengecualian dilemparkan ke dalam fungsi yang dipenuhi atau dilaporkan, status Metode yang dikembalikan Metode, objek janji dikonversi menjadi ditolak. Jika objek Promise memanggil, objek kesalahan akan digunakan sebagai parameter pertama dari fungsi onReChjected.
Jika keadaan janji menjadi terpenuhi dan fungsi yang lebih tinggi tidak disediakan dalam metode itu, keadaan objek janji yang dikembalikan dengan metode kemudian menjadi terpenuhi dan hasil yang berhasil adalah hasil dari janji sebelumnya, hal yang sama berlaku untuk ditolak.
Untuk menambahkan, baik yang dipenuhi dan satu kali dieksekusi secara tidak sinkron.
Implementasi Spesifikasi: Q
Di atas adalah tentang spesifikasi janji, dan yang kita butuhkan adalah implementasinya. Q adalah perpustakaan yang memiliki spesifikasi implementasi yang lebih baik untuk Promise/A+.
Pertama -tama, kita perlu membuat objek janji. Spesifikasi untuk penciptaan objek janji ada dalam janji/b. Saya tidak akan menjelaskan secara rinci di sini, cukup tambahkan kode.
Salinan kode adalah sebagai berikut:
function (flag) {
var defer = q.defer ();
fs.readfile ("a.txt", function (err, data) {
if (err) Defer.REJECT (err);
lain defer.resolve (data);
});
return defer.promise;
}
Implementasi paling janji serupa dalam penciptaan janji. Dengan membuat objek Defer dengan atribut Promise, jika nilainya berhasil diperoleh, Defer.Resolve (nilai) dipanggil, jika gagal, tunduk. Proses ini dapat dipahami sebagai panggilan penundaan. Resolusi mengubah keadaan janji menjadi terpenuhi, dan memanggil penundaan.
Saat menghadapi serangkaian metode asinkron yang berkelanjutan, bagaimana Anda bisa menulis kode yang indah menggunakan janji? Lihatlah contoh berikut.
Salinan kode adalah sebagai berikut:
Promise0.then (function (hasil) {
// dosomething
hasil pengembalian;
}). Kemudian (fungsi (hasil) {
// dosomething
Return Promise1;
}). Kemudian (fungsi (hasil) {
// dosomething
}). Catch (function (ex) {
console.log (ex);
}). akhirnya (function () {
console.log ("final");
});
Dalam kode di atas, metode itu hanya menerima onfulfilled, dan metode penangkapan sebenarnya (nol, onReChjected). Dengan cara ini, selama serangkaian metode asinkron selalu berhasil mengembalikan nilai, kode akan berjalan ke bawah dalam gaya air terjun. Jika salah satu metode asinkron gagal atau pengecualian terjadi, maka menurut spesifikasi janji CommonJS, fungsi dalam tangkapan akan dieksekusi. Q Juga menyediakan metode akhirnya, yang mudah dipahami secara harfiah, yaitu, apakah itu menyelesaikan atau menolak, fungsi di akhirnya akan dieksekusi.
Kelihatannya bagus, kodenya lebih dipertahankan dan indah, jadi bagaimana jika Anda menginginkan konkurensi?
Salinan kode adalah sebagai berikut:
Q.all ([Promise0, Promise1, Promise2]). Spread (Function (Val0, Val1, Val2) {
console.log (argumen);
}). Kemudian (function () {
console.log ("selesai");
}). Catch (function (err) {
console.log (err);
});
Q juga menyediakan API untuk konkurensi, memanggil semua metode dan melewati array janji dapat terus menggunakan gaya rantai kemudian. Ada juga hal -hal baik seperti q.nfbind, dll. Yang dapat mengubah API asli Node.js menjadi janji untuk menyatukan format kode. Lebih banyak API tidak akan dijelaskan secara rinci di sini.
sebagai kesimpulan
Artikel ini terutama memperkenalkan penggunaan janji untuk menyelesaikan masalah aliran kontrol node.js, tetapi janji juga dapat diterapkan ke front-end. Emcascript6 telah memberikan dukungan API asli. Harus ditunjukkan bahwa janji bukan satu -satunya solusi, async juga merupakan pilihan yang baik dan memberikan API kontrol konkurensi yang lebih ramah, tetapi saya pikir janji memiliki lebih banyak keuntungan ketika merangkum fungsi dengan metode asinkron.
Oke, itu saja untuk artikel ini, saya harap ini akan membantu semua orang.