Bagaimana callback diimplementasikan dalam javascript?

Karena fungsi adalah objek kelas satu, kita dapat meneruskan fungsi sebagai argumen di fungsi lain dan kemudian menjalankan fungsi yang diteruskan tersebut atau bahkan mengembalikannya untuk dieksekusi nanti. Ini adalah inti dari penggunaan fungsi callback di JavaScript. Di sisa artikel ini kita akan mempelajari segala sesuatu tentang fungsi callback JavaScript. Fungsi panggilan balik mungkin merupakan teknik pemrograman fungsional yang paling banyak digunakan dalam JavaScript, dan Anda dapat menemukannya di hampir setiap bagian kode JavaScript dan jQuery, namun tetap misterius bagi banyak pengembang JavaScript. Misteri itu tidak akan ada lagi, pada saat Anda selesai membaca artikel ini

Fungsi panggilan balik berasal dari paradigma pemrograman yang dikenal sebagai pemrograman fungsional. Pada tingkat dasar, pemrograman fungsional menentukan penggunaan fungsi sebagai argumen. Pemrograman fungsional adalah — dan masih, meskipun pada tingkat yang jauh lebih rendah saat ini — dilihat sebagai teknik esoterik dari programmer ahli yang terlatih khusus.

Untungnya, teknik pemrograman fungsional telah dijelaskan sehingga manusia biasa seperti Anda dan saya dapat memahami dan menggunakannya dengan mudah. Salah satu teknik utama dalam pemrograman fungsional adalah fungsi callback. Seperti yang akan Anda baca sebentar lagi, mengimplementasikan fungsi callback semudah meneruskan variabel biasa sebagai argumen. Teknik ini sangat sederhana sehingga saya bertanya-tanya mengapa teknik ini sebagian besar tercakup dalam topik JavaScript tingkat lanjut

Apa itu Fungsi Callback atau Higher-order?

Fungsi callback, juga dikenal sebagai fungsi tingkat tinggi, adalah fungsi yang diteruskan ke fungsi lain (sebut saja fungsi lain ini "otherFunction") sebagai parameter, dan fungsi callback dipanggil (atau dijalankan) di dalam fungsi lain. Fungsi panggilan balik pada dasarnya adalah sebuah pola (solusi mapan untuk masalah umum), dan oleh karena itu, penggunaan fungsi panggilan balik juga dikenal sebagai pola panggilan balik

Pertimbangkan penggunaan umum fungsi callback di jQuery

//Note that the item in the click method's parameter is a function, not a variable.
//The item is a callback function
$("#btn_1").click(function() {
  alert("Btn 1 Clicked");
});

Seperti yang Anda lihat pada contoh sebelumnya, kami meneruskan fungsi sebagai parameter ke metode klik. Dan metode click akan memanggil (atau menjalankan) fungsi panggilan balik yang kami berikan padanya. Contoh ini mengilustrasikan penggunaan umum fungsi callback di JavaScript, dan yang banyak digunakan di jQuery

Renungkan contoh klasik fungsi callback lainnya di JavaScript dasar ini

var friends = ["Mike", "Stacy", "Andy", "Rick"];

friends.forEach(function (eachName, index){
console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick
});
_

Sekali lagi, perhatikan cara kami meneruskan fungsi anonim (fungsi tanpa nama) ke metode forEach sebagai parameter

Sejauh ini kita telah melewatkan fungsi anonim sebagai parameter ke fungsi atau metode lain. Sekarang mari kita pahami cara kerja callback sebelum kita melihat contoh yang lebih konkret dan mulai membuat fungsi callback kita sendiri

Bagaimana Fungsi Callback Bekerja?

Kita dapat meneruskan fungsi seperti variabel dan mengembalikannya dalam fungsi dan menggunakannya dalam fungsi lain. Saat kami meneruskan fungsi panggilan balik sebagai argumen ke fungsi lain, kami hanya meneruskan definisi fungsi. Kami tidak menjalankan fungsi di parameter. Dengan kata lain, kita tidak melewatkan fungsi dengan pasangan akhir dari tanda kurung eksekusi () seperti yang kita lakukan saat mengeksekusi sebuah fungsi

Dan karena fungsi yang memuatnya memiliki fungsi panggilan balik dalam parameternya sebagai definisi fungsi, ia dapat menjalankan panggilan balik kapan saja

Perhatikan bahwa fungsi panggilan balik tidak segera dijalankan. Itu "dipanggil kembali" (karena itu namanya) di beberapa titik tertentu di dalam tubuh fungsi yang memuatnya. Jadi, meskipun contoh jQuery pertama terlihat seperti ini

//The anonymous function is not being executed there in the parameter. 
//The item is a callback function
$("#btn_1").click(function() {
  alert("Btn 1 Clicked");
});

fungsi anonim akan dipanggil nanti di dalam badan fungsi. Bahkan tanpa nama, itu masih bisa diakses nanti melalui objek argumen dengan fungsi yang memuatnya

Fungsi Callback Adalah Penutupan
Saat kita meneruskan fungsi panggilan balik sebagai argumen ke fungsi lain, panggilan balik dijalankan di beberapa titik di dalam badan fungsi yang berisi sama seperti jika panggilan balik didefinisikan dalam fungsi yang berisi. Ini berarti panggilan balik adalah penutupan. Baca posting saya, Memahami Penutupan JavaScript Dengan Mudah untuk informasi lebih lanjut tentang penutupan. Seperti yang kita ketahui, penutupan memiliki akses ke ruang lingkup fungsi yang memuat, sehingga fungsi panggilan balik dapat mengakses variabel fungsi yang memuat, dan bahkan variabel dari ruang lingkup global

Prinsip Dasar saat Mengimplementasikan Fungsi Callback

Meskipun tidak rumit, fungsi callback memiliki beberapa prinsip penting yang harus kita ketahui saat mengimplementasikannya

Gunakan Fungsi Bernama ATAU Anonim sebagai Callback
Dalam contoh jQuery dan forEach sebelumnya, kami menggunakan fungsi anonim yang didefinisikan dalam parameter fungsi yang memuatnya. Itu adalah salah satu pola umum untuk menggunakan fungsi callback. Pola populer lainnya adalah mendeklarasikan fungsi bernama dan meneruskan nama fungsi tersebut ke parameter. Pertimbangkan ini

// global variable
var allUserData = [];

// generic logStuff function that prints to console
function logStuff (userData) {
    if ( typeof userData === "string")
    {
        console.log(userData);
    }
    else if ( typeof userData === "object")
    {
        for (var item in userData) {
            console.log(item + ": " + userData[item]);
        }

    }

}

// A function that takes two parameters, the last one a callback function
function getInput (options, callback) {
    allUserData.push (options);
    callback (options);

}

// When we call the getInput function, we pass logStuff as a parameter.
// So logStuff will be the function that will called back (or executed) inside the getInput function
getInput ({name:"Rich", speciality:"JavaScript"}, logStuff);
//  name: Rich
// speciality: JavaScript

Meneruskan Parameter ke Fungsi Panggilan Balik
Karena fungsi panggilan balik hanyalah fungsi normal saat dijalankan, kita dapat meneruskan parameter ke sana. Kita dapat meneruskan salah satu properti fungsi yang memuatnya (atau properti global) sebagai parameter ke fungsi callback. Pada contoh sebelumnya, kita meneruskan opsi sebagai parameter ke fungsi callback. Mari berikan variabel global dan variabel lokal

//Global variable
var generalLastName = "Clinton";

function getInput (options, callback) {
    allUserData.push (options);
// Pass the global variable generalLastName to the callback function
    callback (generalLastName, options);
}
_

Pastikan Callback adalah Fungsi Sebelum Menjalankannya
Itu selalu bijaksana untuk memeriksa apakah fungsi panggilan balik yang diteruskan dalam parameter memang merupakan fungsi sebelum memanggilnya. Selain itu, merupakan praktik yang baik untuk membuat fungsi callback menjadi opsional

Mari refactor fungsi getInput dari contoh sebelumnya untuk memastikan pemeriksaan ini dilakukan

function getInput(options, callback) {
    allUserData.push(options);

    // Make sure the callback is a function
    if (typeof callback === "function") {
    // Call it, since we have confirmed it is callable
        callback(options);
    }
}

Tanpa tanda centang, jika fungsi getInput dipanggil tanpa fungsi panggilan balik sebagai parameter atau sebagai pengganti fungsi, non-fungsi dilewatkan, kode kita akan menghasilkan kesalahan runtime

Masalah Saat Menggunakan Metode Dengan Objek ini sebagai Callback
Ketika fungsi panggilan balik adalah metode yang menggunakan objek ini, kita harus mengubah cara kita menjalankan fungsi panggilan balik untuk mempertahankan konteks objek ini. Atau objek this akan mengarah ke objek jendela global (di browser), jika panggilan balik diteruskan ke fungsi global. Atau itu akan menunjuk ke objek dari metode yang berisi
Mari jelajahi ini dalam kode

// Define an object with some properties and a method
// We will later pass the method as a callback function to another function
var clientData = {
    id: 094545,
    fullName: "Not Set",
    // setUserName is a method on the clientData object
    setUserName: function (firstName, lastName)  {
        // this refers to the fullName property in this object
      this.fullName = firstName + " " + lastName;
    }
}

function getUserInput(firstName, lastName, callback)  {
    // Do other stuff to validate firstName/lastName here

    // Now save the names
    callback (firstName, lastName);
}
_

Dalam contoh kode berikut, ketika clientData. setUserName dijalankan, ini. fullName tidak akan menetapkan properti fullName pada objek clientData. Sebaliknya, itu akan mengatur fullName pada objek window, karena getUserInput adalah fungsi global. Ini terjadi karena this objek dalam fungsi global menunjuk ke objek window

getUserInput ("Barack", "Obama", clientData.setUserName);

console.log (clientData.fullName);// Not Set

// The fullName property was initialized on the window object
console.log (window.fullName); // Barack Obama

Gunakan Fungsi Panggil atau Terapkan Untuk Melestarikan ini
Kami dapat memperbaiki masalah sebelumnya dengan menggunakan fungsi Panggil atau Terapkan (kami akan membahas ini di posting blog lengkap nanti). Untuk saat ini, ketahuilah bahwa setiap fungsi dalam JavaScript memiliki dua metode. Hubungi dan Terapkan. Dan metode ini digunakan untuk mengatur this objek di dalam fungsi dan meneruskan argumen ke fungsi

Panggilan mengambil nilai yang akan digunakan sebagai objek this di dalam fungsi sebagai parameter pertama, dan argumen yang tersisa untuk diteruskan ke fungsi diteruskan secara individual (tentu saja dipisahkan dengan koma). Parameter pertama fungsi Terapkan juga merupakan nilai yang akan digunakan sebagai objek this di dalam fungsi, sedangkan parameter terakhir adalah larik nilai (atau objek argumen) untuk diteruskan ke fungsi

Ini terdengar rumit, tetapi mari kita lihat betapa mudahnya menggunakan Terapkan atau Panggil. Untuk memperbaiki masalah pada contoh sebelumnya, kita akan menggunakan fungsi Apply

//Note that we have added an extra parameter for the callback object, called "callbackObj"
function getUserInput(firstName, lastName, callback, callbackObj)  {
    // Do other stuff to validate name here

    // The use of the Apply function below will set the this object to be callbackObj
    callback.apply (callbackObj, [firstName, lastName]);
}

_

Dengan fungsi Apply mengatur objek this dengan benar, kita sekarang dapat mengeksekusi callback dengan benar dan menyetel properti fullName dengan benar pada objek clientData

// We pass the clientData.setUserName method and the clientData object as parameters. The clientData object will be used by the Apply function to set the this object
getUserInput ("Barack", "Obama", clientData.setUserName, clientData);

// the fullName property on the clientData was correctly set
console.log (clientData.fullName); // Barack Obama
_

Kami juga akan menggunakan fungsi Panggilan, tetapi dalam hal ini kami menggunakan fungsi Terapkan

Beberapa Fungsi Panggilan Balik Diizinkan
Kita bisa melewatkan lebih dari satu fungsi callback ke dalam parameter sebuah fungsi, sama seperti kita bisa melewatkan lebih dari satu variabel. Berikut adalah contoh klasik dengan fungsi AJAX jQuery

var friends = ["Mike", "Stacy", "Andy", "Rick"];

friends.forEach(function (eachName, index){
console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick
});
_0

Masalah Dan Solusi "Callback Hell".

Dalam eksekusi kode asinkron, yang hanya merupakan eksekusi kode dalam urutan apa pun, terkadang memiliki banyak level fungsi panggilan balik sejauh Anda memiliki kode yang terlihat seperti berikut. Kode yang berantakan di bawah ini disebut callback hell karena sulitnya mengikuti kode karena banyaknya callback. Saya mengambil contoh ini dari node-mongodb-native, driver MongoDB untuk Node.js. js. [2]. Contoh kode di bawah ini hanya untuk demonstrasi

var friends = ["Mike", "Stacy", "Andy", "Rick"];

friends.forEach(function (eachName, index){
console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick
});
_1

Anda mungkin tidak akan sering menghadapi masalah ini dalam kode Anda, tetapi ketika Anda melakukannya—dan Anda akan mengalaminya dari waktu ke waktu—berikut adalah dua solusi untuk masalah ini. [3]

  1. Beri nama fungsi Anda dan nyatakan dan berikan nama fungsi saja sebagai panggilan balik, alih-alih mendefinisikan fungsi anonim di parameter fungsi utama
  2. Modularitas. Pisahkan kode Anda ke dalam modul, sehingga Anda dapat mengekspor bagian kode yang melakukan tugas tertentu. Kemudian Anda dapat mengimpor modul itu ke dalam aplikasi Anda yang lebih besar

Buat Fungsi Panggilan Balik Anda Sendiri

Sekarang Anda sepenuhnya (saya pikir Anda melakukannya; jika tidak, baca ulang dengan cepat. )) memahami segala sesuatu tentang fungsi callback JavaScript dan Anda telah melihat bahwa menggunakan fungsi callback agak sederhana namun kuat, Anda harus melihat kode Anda sendiri untuk peluang menggunakan fungsi callback, karena mereka akan memungkinkan Anda untuk

  • Jangan ulangi kode (KERING—Jangan Ulangi Sendiri)
  • Terapkan abstraksi yang lebih baik di mana Anda dapat memiliki lebih banyak fungsi generik yang serbaguna (dapat menangani semua jenis fungsi)
  • Memiliki pemeliharaan yang lebih baik
  • Memiliki kode yang lebih mudah dibaca
  • Memiliki fungsi yang lebih terspesialisasi

Agak mudah untuk membuat fungsi callback Anda sendiri. Dalam contoh berikut, saya dapat membuat satu fungsi untuk melakukan semua pekerjaan. mengambil data pengguna, membuat puisi generik dengan data, dan menyapa pengguna. Ini akan menjadi fungsi yang berantakan dengan banyak pernyataan if/else dan, bahkan tetap saja, itu akan sangat terbatas dan tidak mampu menjalankan fungsi lain yang mungkin diperlukan aplikasi dengan data pengguna

Alih-alih, saya meninggalkan implementasi untuk fungsionalitas tambahan hingga fungsi panggilan balik, sehingga fungsi utama yang mengambil data pengguna dapat melakukan hampir semua tugas dengan data pengguna hanya dengan meneruskan nama lengkap dan jenis kelamin pengguna sebagai parameter ke fungsi panggilan balik dan

Singkatnya, fungsi getUserInput bersifat serbaguna. itu dapat menjalankan semua jenis fungsi panggilan balik dengan segudang fungsi

var friends = ["Mike", "Stacy", "Andy", "Rick"];

friends.forEach(function (eachName, index){
console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick
});
_2

Panggil fungsi getUserInput dan teruskan fungsi genericPoemMaker sebagai panggilan balik

var friends = ["Mike", "Stacy", "Andy", "Rick"];

friends.forEach(function (eachName, index){
console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick
});
_3

Karena fungsi getUserInput hanya menangani pengambilan data, kita dapat meneruskan panggilan balik apa pun ke sana. Misalnya, kita bisa melewatkan fungsi greetUser seperti ini

var friends = ["Mike", "Stacy", "Andy", "Rick"];

friends.forEach(function (eachName, index){
console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick
});
_4

Kami memanggil fungsi getUserInput yang sama seperti yang kami lakukan sebelumnya, tetapi kali ini melakukan tugas yang sama sekali berbeda

Seperti yang Anda lihat, fungsi panggilan balik menghasilkan banyak keserbagunaan. Dan meskipun contoh sebelumnya relatif sederhana, bayangkan berapa banyak pekerjaan yang dapat Anda selamatkan sendiri dan seberapa baik abstraksi kode Anda jika Anda mulai menggunakan fungsi callback. Pergi untuk itu. Lakukan di monings;

Perhatikan cara-cara berikut kami sering menggunakan fungsi panggilan balik dalam JavaScript, terutama dalam pengembangan aplikasi web modern, di perpustakaan, dan dalam kerangka kerja

  • Untuk eksekusi asinkron (seperti membaca file, dan membuat permintaan HTTP)
  • Di Pendengar/Penangan Acara
  • Dalam metode setTimeout dan setInterval
  • Untuk Generalisasi. kekompakan kode

Kata Akhir

Fungsi panggilan balik JavaScript luar biasa dan kuat untuk digunakan dan memberikan manfaat besar untuk aplikasi dan kode web Anda. Anda harus menggunakannya saat dibutuhkan;

Sampai jumpa lagi, dan ingat untuk terus kembali karena JavaScriptIsSexy. com memiliki banyak hal untuk mengajari Anda dan Anda harus banyak belajar

Bagaimana cara kerja panggilan balik dalam JavaScript?

Fungsi panggilan balik adalah fungsi yang diteruskan ke fungsi lain sebagai argumen, yang kemudian dipanggil di dalam fungsi luar untuk menyelesaikan semacam rutinitas atau tindakan. The above example is a synchronous callback, as it is executed immediately.

Bagaimana Anda menerapkan fungsi panggilan balik?

Fungsi callback khusus dapat dibuat dengan menggunakan kata kunci callback sebagai parameter terakhir . Itu kemudian dapat dipanggil dengan memanggil fungsi callback() di akhir fungsi. Operator typeof secara opsional digunakan untuk memeriksa apakah argumen yang diteruskan sebenarnya adalah fungsi. menghibur.

Apa itu implementasi callback?

Callback adalah mekanisme dalam Pemrograman Berorientasi Objek yang memungkinkan aplikasi menangani event langganan, yang muncul saat runtime, melalui antarmuka pendengar . Pelanggan perlu menyediakan implementasi konkret dari metode abstrak antarmuka.

Kapan panggilan balik dijalankan?

Fungsi panggilan balik adalah fungsi yang terjadi setelah beberapa peristiwa terjadi. Referensi dalam memori ke fungsi callback biasanya diteruskan ke fungsi lain. Hal ini memungkinkan fungsi lain untuk mengeksekusi callback ketika telah menyelesaikan tugasnya dengan menggunakan sintaks khusus bahasa untuk mengeksekusi suatu fungsi.