Misalkan Anda mempertahankan pustaka yang mengekspos suatu fungsi getData
. Pengguna Anda menyebutnya untuk mendapatkan data aktual:
var output = getData();
Di balik terpal data disimpan dalam file sehingga Anda menerapkannya getData
menggunakan Node.js bawaan fs.readFileSync
. Sudah jelas keduanya getData
dan fs.readFileSync
merupakan fungsi sinkronisasi. Suatu hari Anda diminta untuk mengalihkan sumber data yang mendasari ke repo seperti MongoDB yang hanya dapat diakses secara asinkron. Anda juga diberitahu untuk menghindari membuat pengguna Anda kesal, getData
API tidak dapat diubah untuk hanya mengembalikan sebuah janji atau meminta parameter callback. Bagaimana Anda memenuhi kedua persyaratan tersebut?
Fungsi asynchronous menggunakan callback / promise adalah DNA JavasSript dan Node.js. Aplikasi JS non-sepele apa pun mungkin diresapi dengan gaya pengkodean ini. Tapi praktik ini dapat dengan mudah mengarah pada apa yang disebut piramida malapetaka panggilan balik. Lebih buruk lagi, jika kode apa pun di pemanggil mana pun dalam rantai panggilan bergantung pada hasil dari fungsi asinkron, kode tersebut harus dibungkus dalam fungsi panggilan balik juga, sehingga menerapkan batasan gaya pengkodean pada pemanggil. Dari waktu ke waktu saya merasa perlu untuk merangkum fungsi async (sering disediakan di perpustakaan pihak ke-3) ke dalam fungsi sinkronisasi untuk menghindari pemfaktoran ulang global secara besar-besaran. Mencari solusi tentang masalah ini biasanya berakhir dengan Node Fibers atau paket npm yang diturunkan darinya. Tapi Serat tidak bisa menyelesaikan masalah yang saya hadapi. Bahkan contoh yang diberikan oleh penulis Fibers menggambarkan kekurangannya:
...
Fiber(function() {
console.log('wait... ' + new Date);
sleep(1000);
console.log('ok... ' + new Date);
}).run();
console.log('back in main');
Output aktual:
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
Jika fungsi Fiber benar-benar mengubah fungsi async menjadi sinkron, outputnya harus:
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
back in main
Saya telah membuat contoh sederhana lainnya di JSFiddle dan mencari kode untuk menghasilkan keluaran yang diharapkan. Saya akan menerima solusi yang hanya berfungsi di Node.js sehingga Anda bebas memerlukan paket npm apa pun meskipun tidak berfungsi di JSFiddle.