Saya baru saja mulai menggunakan node, dan satu hal yang saya perhatikan dengan cepat adalah seberapa cepat callback dapat membangun ke tingkat indentasi yang konyol:
doStuff(arg1, arg2, function(err, result) {
doMoreStuff(arg3, arg4, function(err, result) {
doEvenMoreStuff(arg5, arg6, function(err, result) {
omgHowDidIGetHere();
});
});
});
The panduan gaya resmi mengatakan untuk menempatkan setiap panggilan balik dalam fungsi yang terpisah, tapi itu tampaknya terlalu ketat pada penggunaan penutupan, dan membuat satu objek dideklarasikan di tingkat atas tersedia beberapa lapisan bawah, sebagai objek tersebut harus melewati semua panggilan balik menengah.
Apakah boleh menggunakan lingkup fungsi untuk membantu di sini? Letakkan semua fungsi panggilan balik yang membutuhkan akses ke objek global di dalam fungsi yang menyatakan objek itu, jadi ia akan ditutup?
function topLevelFunction(globalishObject, callback) {
function doMoreStuffImpl(err, result) {
doMoreStuff(arg5, arg6, function(err, result) {
callback(null, globalishObject);
});
}
doStuff(arg1, arg2, doMoreStuffImpl);
}
dan seterusnya untuk beberapa lapisan lagi ...
Atau apakah ada kerangka kerja dll untuk membantu mengurangi tingkat indentasi tanpa mendeklarasikan fungsi yang disebutkan untuk setiap panggilan balik tunggal? Bagaimana Anda menangani piramida callback?
sumber
Jawaban:
Ada beberapa implementasi "janji":
Misalnya, Anda dapat menulis ulang callback bersarang ini
Suka
Alih-alih panggilan balik dalam panggilan balik
a(b(c()))
Anda rantai ".then"a().then(b()).then(c())
.Pengantar di sini: http://howtonode.org/promises
sumber
Sebagai alternatif dari janji-janji Anda harus melihat
yield
kata kunci dalam kombinasi dengan fungsi generator yang akan diperkenalkan di EcmaScript 6. Keduanya tersedia hari ini di Node.js 0.11.x builds, tetapi mengharuskan Anda tambahan menentukan--harmony
bendera saat menjalankan Node .js:Menggunakan konstruk dan pustaka seperti TJ Holowaychuk's co memungkinkan Anda untuk menulis kode asinkron dengan gaya yang terlihat seperti kode sinkron, meskipun masih berjalan dengan cara yang tidak sinkron. Pada dasarnya, semua ini bersama-sama mengimplementasikan dukungan rutin bersama untuk Node.js.
Pada dasarnya, apa yang perlu Anda lakukan adalah menulis fungsi generator untuk kode yang menjalankan hal-hal asinkron, panggil hal-hal async di sana, tetapi awali dengan
yield
kata kunci. Jadi, pada akhirnya kode Anda terlihat seperti:Untuk menjalankan fungsi generator ini, Anda memerlukan pustaka seperti co yang disebutkan sebelumnya. Panggilannya kemudian terlihat seperti:
Atau, untuk membuatnya sejajar:
Harap dicatat bahwa dari fungsi-fungsi generator Anda dapat memanggil fungsi-fungsi generator lainnya, yang perlu Anda lakukan adalah awalan dengan fungsi-fungsi tersebut
yield
lagi.Untuk pengantar topik ini, cari Google untuk istilah seperti
yield generators es6 async nodejs
dan Anda harus menemukan banyak informasi. Butuh beberapa saat untuk membiasakan diri, tetapi begitu Anda mendapatkannya, Anda tidak ingin kembali lagi.Harap dicatat bahwa ini tidak hanya menyediakan Anda dengan sintaks yang lebih baik untuk memanggil fungsi, tetapi juga memungkinkan Anda untuk menggunakan hal-hal logika aliran kontrol (sinkron) yang biasa, seperti
for
loop atautry
/catch
. Tidak perlu lagi dipusingkan dengan banyak panggilan balik dan semua hal ini.Semoga berhasil dan selamat bersenang - senang :-)!
sumber
Anda sekarang memiliki paket asyncawait , dengan sintaks yang sangat dekat dengan apa yang seharusnya menjadi dukungan asli masa depan dari
await
&async
di Node.Pada dasarnya memungkinkan Anda untuk menulis kode asinkron yang terlihat sinkron , mengurangi LOC & tingkat indentasi secara dramatis, dengan tradeoff kehilangan kinerja yang sedikit (nomor pemilik paket adalah kecepatan 79% dibandingkan dengan panggilan balik mentah), mudah-mudahan berkurang ketika dukungan asli akan tersedia.
Masih merupakan pilihan yang baik untuk keluar dari neraka panggilan balik / piramida malapetaka IMO, ketika kinerja bukan perhatian utama & di mana gaya penulisan sinkron lebih sesuai dengan kebutuhan proyek Anda.
Contoh dasar dari paket doc:
sumber