Beberapa hari ini saya ikut duduk di sesi wawancara dengan kandidat-kandidat yang ingin bergabung bersama Pak MDAMT di HOOQ Bandung. Salah satu templat pertanyaan adalah apakah kandidat mengenal Promise
. Tentu pengembang JavaScript, apalagi yang sering bermain dengan Node sudah sangat paham dengan ini. Yang menarik, tidak semua dengan serta merta dapat secara "manual" mengubah fungsi berbasis callback menjadi fungsi yang mengembalikan Promise
.
Ada beberapa kandidat menggunakan fasilitas promisify
dari bluebird. Alasannya? Karena praktis dan cukup panggil satu fungsi, dan secara sulap mengubah fungsi berbasis callback menjadi mengembalikan Promise
.
Tapi jarang yang paham, alasan bluebird punya tagline "...full featured promise library with unmatched performance", apalagi ketika berjalan di node.
Jika kita baca fungsi promisify
, https://github.com/petkaantonov/bluebird/blob/master/src/promisify.js ini kenapa repot-repot Pak Petka Antonov punya treatment berbeda untuk node?
Sebelumnya, fungsi promisify
itu seperti berikut:
function promisify(callback, receiver, multiArgs) {
return makeNodePromisified(callback, receiver, undefined,
callback, null, multiArgs);
}
callback
adalah fungsi berbasis callback seperti misalnya fs.readFile
, sedangkan receiver adalah jadi this
-nya (object tempat si callback bekerja). Sedangkan multiArgs
untuk mengirim argumen dalam bentuk array ke fungsi callback
.
Untuk mengecek apakah sedang berjalan di node, cukup cek flag berikut:
const canEvaluate = util.canEvaluate;
Dari situ kita telusuri bahwa ada kondisi:
var makeNodePromisified = canEvaluate
? makeNodePromisifiedEval
: makeNodePromisifiedClosure;
Jadi ketika di node, bluebird akan jalankan makeNodePromisifiedEval
dan ketika di peramban akan memanggil makeNodePromisifiedClosure
.
Lompat ke dalam fungsi makeNodePromisifiedEval
kita lihat ada generateCallForArgumentCount
.
Dan di situ ada hasil pembangkitan kode dengan baris: callback.call
. Di sini terlihat bahwa Pak Petka juga akan melakukan generateArgumentSwitchCase
, yaitu akibat pilihan beliau menggunakan callback.call
daripada callback.apply
. Yang terakhir tentu lebih mudah tanpa harus switch-case
terhadap jumlah argumen karena callback.apply
masukannya adalah array.
Terus kenapa memaksa untuk menggunakan callback.call
? Jawabannya node menggunakan v8, dan ibu dari segala optimisasi adalah inlining, dan callback.call
dapat di-inlining sedangkan callback.apply
tidak.
Jika kita baca lagi promisify.js yang seru adalah menentukan jumlah argumen yang mungkin kemudian dibangkitkan kode switch-case berdasarkan jumlah argumen. Seru!
Mari kita interview lagi Pak MDAMT!