Skip to content

Instantly share code, notes, and snippets.

@diorahman
Last active September 10, 2016 03:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save diorahman/3cf9e228694adf73f651144f34d1ec06 to your computer and use it in GitHub Desktop.
Save diorahman/3cf9e228694adf73f651144f34d1ec06 to your computer and use it in GitHub Desktop.

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment