Apa itu fungsi callback?

684

Apa itu fungsi callback?

Cheekysoft
sumber
8
Anda dapat menemukan di sini: stackoverflow.com/a/9652434/3343174 penjelasan terbaik tentang callback
Fakher
Lihatlah jawaban kedua untuk penjelasan detail
Donato
Penjelasan terbaik tentang panggilan balik yang pernah saya temukan youtube.com/watch?v=xHneyv38Jro
Sameer Sinha

Jawaban:

680

Pengembang sering bingung dengan panggilan balik apa karena nama benda terkutuk itu.

Fungsi panggilan balik adalah fungsi yang:

  • dapat diakses oleh fungsi lain, dan
  • dipanggil setelah fungsi pertama jika fungsi pertama selesai

Cara yang bagus untuk membayangkan bagaimana fungsi panggilan balik bekerja adalah bahwa itu adalah fungsi yang " dipanggil di bagian belakang " dari fungsi yang dilaluinya.

Mungkin nama yang lebih baik akan menjadi fungsi "panggilan setelah" .

Konstruk ini sangat berguna untuk perilaku asinkron di mana kami ingin aktivitas berlangsung setiap kali acara sebelumnya selesai.

Kodesemu:

// A function which accepts another function as an argument
// (and will automatically invoke that function when it completes - note that there is no explicit call to callbackFunction)
funct printANumber(int number, funct callbackFunction) {
    printout("The number you provided is: " + number);
}

// a function which we will use in a driver function as a callback function
funct printFinishMessage() {
    printout("I have finished printing numbers.");
}

// Driver method
funct event() {
   printANumber(6, printFinishMessage);
}

Hasil jika Anda memanggil acara ():

The number you provided is: 6
I have finished printing numbers.

Urutan output di sini penting. Karena fungsi panggilan balik dipanggil setelah itu, "Saya telah selesai mencetak nomor" dicetak terakhir, bukan yang pertama.

Panggilan balik disebut karena penggunaannya dengan bahasa penunjuk. Jika Anda tidak menggunakan salah satunya, jangan coba-coba menyebut nama 'panggilan balik'. Hanya mengerti bahwa itu hanya nama untuk menggambarkan metode yang disediakan sebagai argumen ke metode lain, sehingga ketika metode induk dipanggil (kondisi apa pun, seperti klik tombol, centang timer dll) dan badan metodenya selesai, fungsi panggilan balik kemudian dipanggil.

Beberapa bahasa mendukung konstruk di mana beberapa argumen fungsi panggilan balik didukung, dan dipanggil berdasarkan pada bagaimana fungsi induk selesai (yaitu satu panggilan balik dipanggil jika fungsi orangtua berhasil diselesaikan, yang lain dipanggil jika acara fungsi induk melempar kesalahan spesifik, dll).

8bitjunkie
sumber
31
Contoh Anda sangat bagus tapi saya tidak mengerti mengapa istilahnya adalah "panggilan balik". Kapan meaningOfLife "dipanggil kembali"?
CodyBugstein
4
Halo, tentang once its parent method completes, the function which this argument represents is then called. Jadi jika fungsi dilewatkan ke fungsi lain sebagai argumen tetapi dipanggil dari tengah runtime fungsi orangtua seperti parent(cb) {dostuff1(); cb(); dostuff2()}maka itu tidak dianggap sebagai callbackfungsi?
Max Yari
2
@ Maxiari: IMHO, masih dianggap sebagai callback. Yang penting di sini adalah bahwa functin induk akan menggunakan fungsi input (alias panggilan balik) entah bagaimana. Dapat disebut di tengah atau di akhir atau jika suatu kondisi terpenuhi.
Kamran Bigdely
12
@ 8bitjunkie terima kasih - tetapi di mana metode meaningOfLife dipanggil dalam fungsi printANumber?
BKSpurgeon
2
Ini tidak benar sama sekali: "secara otomatis dipanggil setelah fungsi pertama selesai". Panggilan balik tidak harus dilakukan sama sekali, apalagi secara otomatis. Bahkan, tidak jarang panggilan balik selesai sebelum fungsi induk selesai. Saya sangat tidak suka bagaimana orang menggambarkan panggilan balik sebagai fungsi yang dieksekusi "nanti". Sangat membingungkan bagi orang yang belajar tentang mereka. Sederhananya, panggilan balik hanya fungsi yang diteruskan sebagai argumen ke fungsi lain. Titik. Penjelasan yang lebih baik akan mencakup menjelaskan MENGAPA panggilan balik atas referensi fungsi.
Jordan
224

Definisi Buram

Fungsi panggilan balik adalah fungsi yang Anda berikan ke bagian kode lain, yang memungkinkannya dipanggil oleh kode itu.

Contoh buatan

Mengapa Anda ingin melakukan ini? Katakanlah ada layanan yang perlu Anda panggil. Jika layanan segera kembali, Anda hanya:

  1. Sebut saja
  2. Tunggu hasilnya
  3. Lanjutkan begitu hasilnya masuk

Sebagai contoh, misalkan layanan adalah factorialfungsi. Ketika Anda menginginkan nilai 5!, Anda akan memohon factorial(5), dan langkah-langkah berikut akan terjadi:

  1. Lokasi eksekusi Anda saat ini disimpan (di stack, tapi itu tidak penting)

  2. Eksekusi diserahkan kepada factorial

  3. Ketika factorialselesai, ia menempatkan hasilnya di suatu tempat yang bisa Anda dapatkan

  4. Eksekusi kembali ke tempatnya semula [1]

Sekarang anggaplah factorialbutuh waktu yang sangat lama, karena Anda memberikannya jumlah yang besar dan perlu dijalankan pada beberapa cluster superkomputer di suatu tempat. Katakanlah Anda mengharapkan waktu 5 menit untuk mengembalikan hasil Anda. Anda bisa:

  1. Jaga desain Anda dan jalankan program Anda di malam hari saat Anda tidur, sehingga Anda tidak menatap layar setengah waktu

  2. Rancang program Anda untuk melakukan hal-hal lain saat factorialmelakukan hal tersebut

Jika Anda memilih opsi kedua, maka panggilan balik mungkin cocok untuk Anda.

Desain ujung ke ujung

Untuk mengeksploitasi pola panggilan balik, yang Anda inginkan adalah dapat memanggil factorialdengan cara berikut:

factorial(really_big_number, what_to_do_with_the_result)

Parameter kedua what_to_do_with_the_result,, adalah fungsi yang Anda kirim factorial, dengan harapan factorialakan memanggil hasilnya sebelum kembali.

Ya, ini berarti factorialharus ditulis untuk mendukung panggilan balik.

Sekarang anggaplah Anda ingin dapat mengirimkan parameter ke panggilan balik Anda. Sekarang Anda tidak bisa, karena Anda tidak akan memanggilnya, factorialadalah. Jadi factorialperlu ditulis untuk memungkinkan Anda memasukkan parameter Anda, dan itu hanya akan menyerahkannya ke callback Anda ketika dipanggil. Mungkin terlihat seperti ini:

factorial (number, callback, params)
{
    result = number!   // i can make up operators in my pseudocode
    callback (result, params)
}

Sekarang factorialmemungkinkan pola ini, panggilan balik Anda mungkin terlihat seperti ini:

logIt (number, logger)
{
    logger.log(number)
}

dan panggilan Anda untuk factorialmenjadi

factorial(42, logIt, logger)

Bagaimana jika Anda ingin mengembalikan sesuatu logIt? Ya, Anda tidak bisa, karena factorialtidak memperhatikannya.

Nah, mengapa tidak bisa factorialmengembalikan apa yang dikembalikan oleh callback Anda?

Menjadikannya tidak menghalangi

Karena eksekusi dimaksudkan untuk diserahkan ke callback ketika factorialselesai, itu benar-benar tidak boleh mengembalikan apa pun kepada peneleponnya. Dan idealnya, entah bagaimana ia akan meluncurkan pekerjaannya di utas / proses / mesin lain dan segera kembali sehingga Anda dapat melanjutkan, mungkin seperti ini:

factorial(param_1, param_2, ...)
{
    new factorial_worker_task(param_1, param_2, ...);
    return;
}

Ini sekarang merupakan "panggilan tidak sinkron", yang berarti bahwa ketika Anda memanggilnya, ia segera kembali tetapi belum benar-benar melakukan tugasnya. Jadi Anda perlu mekanisme untuk memeriksanya, dan untuk mendapatkan hasilnya setelah selesai, dan program Anda menjadi semakin rumit dalam prosesnya.

Dan omong-omong, menggunakan pola ini, Anda factorial_worker_taskdapat meluncurkan panggilan balik secara asinkron dan segera kembali.

Jadi apa yang kamu lakukan?

Jawabannya adalah tetap dalam pola panggilan balik. Kapan pun Anda ingin menulis

a = f()
g(a)

dan fakan dipanggil secara tidak sinkron, sebagai gantinya Anda akan menulis

f(g)

di mana gdilewatkan sebagai panggilan balik.

Ini secara mendasar mengubah aliran-topologi program Anda , dan membutuhkan waktu untuk membiasakan diri.

Bahasa pemrograman Anda dapat banyak membantu Anda dengan memberi Anda cara untuk membuat berbagai fungsi dengan cepat. Dalam kode tepat di atas, fungsinya gmungkin sekecil print (2*a+1). Jika bahasa Anda mengharuskan Anda mendefinisikan ini sebagai fungsi terpisah, dengan nama dan tanda tangan yang sama sekali tidak perlu, maka hidup Anda akan menjadi tidak menyenangkan jika Anda sering menggunakan pola ini.

Jika, di sisi lain, bahasa Anda memungkinkan Anda membuat lambda, maka Anda berada dalam kondisi yang jauh lebih baik. Anda kemudian akan menulis sesuatu seperti

f( func(a) { print(2*a+1); })

yang jauh lebih baik.

Bagaimana cara melewati callback

Bagaimana Anda akan meneruskan fungsi panggilan balik factorial? Nah, Anda bisa melakukannya dengan beberapa cara.

  1. Jika fungsi yang dipanggil berjalan dalam proses yang sama, Anda bisa melewatkan pointer fungsi

  2. Atau mungkin Anda ingin mempertahankan kamus fn name --> fn ptrdi program Anda, dalam hal ini Anda bisa memberikan nama

  3. Mungkin bahasa Anda memungkinkan Anda untuk mendefinisikan fungsi di tempat, mungkin sebagai lambda! Secara internal itu menciptakan semacam objek dan melewati pointer, tetapi Anda tidak perlu khawatir tentang itu.

  4. Mungkin fungsi yang Anda panggil sedang berjalan pada mesin yang sepenuhnya terpisah, dan Anda memanggilnya menggunakan protokol jaringan seperti HTTP. Anda bisa mengekspos callback Anda sebagai fungsi HTTP-callable, dan meneruskan URL-nya.

Anda mendapatkan idenya.

Peningkatan callback baru-baru ini

Di era web ini yang telah kita masukkan, layanan yang kita gunakan sering melalui jaringan. Kami sering tidak memiliki kendali atas layanan-layanan tersebut, yaitu kami tidak menulisnya, kami tidak memeliharanya, kami tidak dapat memastikan semuanya berjalan atau bagaimana kinerjanya.

Tetapi kami tidak dapat mengharapkan program kami untuk diblokir sementara kami menunggu layanan ini merespons. Menyadari hal ini, penyedia layanan sering merancang API menggunakan pola panggilan balik.

JavaScript mendukung panggilan balik dengan sangat baik misalnya dengan lambdas dan penutupan. Dan ada banyak aktivitas di dunia JavaScript, baik di browser maupun di server. Bahkan ada platform JavaScript yang dikembangkan untuk seluler.

Ketika kita bergerak maju, semakin banyak dari kita akan menulis kode asinkron, yang karenanya pemahaman ini akan sangat penting.

Rohit Chatterjee
sumber
1
Sebuah konsep yang dijelaskan dengan sangat baik ..! :)
piyushGoyal
Penjelasan hebat, +1.
Lingamurthy CS
1
Ini adalah jawaban terbaik di antara yang lainnya. Mohon angkat suara itu.
Abhishek Nalin
3
Dijelaskan dengan sempurna dan semuanya dijelaskan. Saya berharap saya dapat memperbaikinya lagi.
Yogesh Yadav
Ya saya mengerti bagaimana lambas bekerja di javascript dan ruby. Dan java 8 tetapi versi lama java tidak menggunakan lambas dan sebagai gantinya menggunakan kelas dan saya ingin tahu bagaimana cara kerja callback semacam itu. Masih jawaban superior untuk yang lain.
Donato
96

Perhatikan bahwa panggilan balik adalah satu kata.

Halaman panggilan balik wikipedia menjelaskannya dengan sangat baik.

kutipan dari halaman wikipedia:

Dalam pemrograman komputer, panggilan balik adalah referensi ke kode yang dapat dieksekusi, atau bagian dari kode yang dapat dieksekusi, yang diteruskan sebagai argumen ke kode lain. Ini memungkinkan lapisan perangkat lunak tingkat rendah untuk memanggil subrutin (atau fungsi) yang didefinisikan dalam lapisan tingkat yang lebih tinggi.

danio
sumber
14
Cara yang bagus untuk menyajikan jawaban.
Chathuranga Chandrasekara
1
Dan ini juga mengarah pada jawaban dengan cara yang berbeda. Kata benda "callback" adalah yang telah "dipanggil kembali", dengan cara yang sama sesuatu yang telah melalui shutdown telah dimatikan dan sesuatu yang digunakan untuk login adalah login.
Anonim
22
Ini bisa menjadi komentar - pada dasarnya itu adalah tautan ke Wikipedia
CodyBugstein
Wikipedia sebenarnya memiliki beberapa hal pemrograman yang sangat luar biasa di dalamnya. Saya selalu merasa istilah "panggilan balik" paling baik dijelaskan dengan menggunakan ungkapan, "Saya akan menelepon kembali ke ..."
Thomas
Penjelasan hebat di javascriptissexy.com/…; yang akan saya posting ulang di sini; Fungsi panggilan balik adalah fungsi yang diteruskan ke fungsi lain sebagai parameter, dan fungsi panggilan balik dipanggil atau dieksekusi di dalam Fungsi lainnya. // Perhatikan bahwa item dalam parameter metode klik adalah fungsi, bukan variabel. // Item tersebut adalah fungsi panggilan balik $ ("# btn_1"). Klik (function () {alert ("Btn 1 Clicked" );}); Seperti yang Anda lihat pada contoh sebelumnya, kami meneruskan fungsi sebagai parameter ke metode klik untuk dieksekusi -
MarcoZen
46

Respons awam adalah bahwa itu adalah fungsi yang tidak dipanggil oleh Anda melainkan oleh pengguna atau browser setelah peristiwa tertentu terjadi atau setelah beberapa kode diproses.

NateH
sumber
42

Fungsi panggilan balik adalah fungsi yang harus dipanggil ketika kondisi tertentu terpenuhi. Alih-alih dipanggil segera, fungsi callback dipanggil pada titik tertentu di masa depan.

Biasanya ini digunakan ketika tugas sedang dimulai yang akan selesai secara tidak sinkron (yaitu akan selesai beberapa saat setelah fungsi panggilan telah kembali).

Misalnya, suatu fungsi untuk meminta halaman web mungkin memerlukan pemanggilnya untuk menyediakan fungsi panggilan balik yang akan dipanggil ketika halaman web telah selesai mengunduh.

Thomas Bratt
sumber
Dalam kalimat pertama Anda, Anda mengatakan "...when a condition is met"tetapi saya pikir panggilan balik dipanggil ketika fungsi induk selesai dijalankan dan tidak tergantung pada kondisi (?).
Ojonugwa Jude Ochalifu
'Kondisi tertentu' hanya berarti mereka secara umum dipanggil karena suatu alasan, bukan secara acak. Callback dapat dipanggil ketika orang tua / pembuat masih mengeksekusi - ini dapat menyebabkan kondisi ras jika programmer tidak mengharapkannya.
Thomas Bratt
Oke. Terima kasih atas klarifikasi
Ojonugwa Jude Ochalifu
34

Panggilan balik paling mudah dijelaskan dalam hal sistem telepon. Panggilan fungsi analog dengan memanggil seseorang di telepon, mengajukan pertanyaan kepadanya, mendapatkan jawaban, dan menutup telepon; menambahkan callback mengubah analoginya sehingga setelah mengajukan pertanyaan kepadanya, Anda juga memberikan nama dan nomor Anda sehingga dia dapat menghubungi Anda kembali dengan jawabannya.

- Paul Jakubik, "Implementasi Callback di C ++"

DejanLekic
sumber
1
Jadi nama dan nomor saya adalah fungsi?
Koray Tugay
Tidak, itu akan menjadi analogi jika "panggilan balik" adalah nama yang bagus untuk apa yang sebaliknya: Anda meminta operator telepon untuk melakukan panggilan. Tamat.
gherson
33

Saya percaya jargon "panggilan balik" ini telah digunakan secara keliru di banyak tempat. Definisi saya akan seperti:

Fungsi panggilan balik adalah fungsi yang Anda berikan kepada seseorang dan biarkan mereka memanggilnya pada suatu saat.

Saya pikir orang baru saja membaca kalimat pertama dari definisi wiki:

panggilan balik adalah referensi ke kode yang dapat dieksekusi, atau bagian dari kode yang dapat dieksekusi, yang diteruskan sebagai argumen ke kode lain.

Saya telah bekerja dengan banyak API, lihat berbagai contoh buruk. Banyak orang cenderung menamai penunjuk fungsi (referensi ke kode yang dapat dieksekusi) atau fungsi anonim (sepotong kode yang dapat dieksekusi) "callback", jika mereka hanya berfungsi mengapa Anda memerlukan nama lain untuk ini?

Sebenarnya hanya kalimat kedua dalam definisi wiki yang mengungkapkan perbedaan antara fungsi panggilan balik dan fungsi normal:

Ini memungkinkan lapisan perangkat lunak tingkat rendah untuk memanggil subrutin (atau fungsi) yang didefinisikan dalam lapisan tingkat yang lebih tinggi.

jadi perbedaannya adalah siapa Anda akan melewati fungsi dan bagaimana fungsi Anda lewat akan dipanggil. Jika Anda hanya mendefinisikan suatu fungsi dan meneruskannya ke fungsi lain dan memanggilnya langsung di badan fungsi itu, jangan panggil itu panggilan balik. Definisi tersebut mengatakan fungsi yang Anda operasikan akan dipanggil oleh fungsi "tingkat bawah".

Saya harap orang-orang dapat berhenti menggunakan kata ini dalam konteks ambigu, itu tidak dapat membantu orang untuk memahami lebih baik hanya lebih buruk.

Zane XY
sumber
2
Jawaban Anda masuk akal ... tapi saya kesulitan membayangkannya. Bisakah Anda memberi contoh?
CodyBugstein
3
@Ane Wong :: Pada yang terakhir Anda telah menulis "Definisi mengatakan bahwa fungsi Anda yang lewat akan dipanggil oleh fungsi" tingkat rendah "." Bisakah Anda jelaskan apa yang ditunjukkan fungsi tingkat bawah? Lebih baik jika Anda memberi contoh.
Viku
Sebuah contoh akan menyenangkan
Yousuf Azad
1
Saya pikir perbedaan antara panggilan fungsi klasik dan gaya panggilan balik adalah tautan ke arah dependy: jika modul A bergantung pada ("menggunakan") modul B, A memanggil fungsi B, itu bukan panggilan balik. Jika A meneruskan referensi ke fungsinya ke B, maka B memanggil fungsi A, ini adalah callback: panggilan mundur dibandingkan dengan ketergantungan modul.
XouDo
30

Mari kita tetap sederhana. Apa itu fungsi panggilan balik?

Contoh oleh Perumpamaan dan Analogi

Saya punya sekretaris. Setiap hari saya memintanya untuk: (i) mengirim surat keluar perusahaan di kantor pos, dan setelah dia melakukannya, untuk melakukan: (ii) tugas apa pun yang saya tulis untuknya di salah satu catatan tempel itu .

Sekarang, apa tugas pada catatan tempel? Tugasnya bervariasi dari hari ke hari.

Misalkan pada hari tertentu ini, saya meminta dia untuk mencetak beberapa dokumen. Jadi saya menuliskannya pada catatan tempel, dan saya menempelkannya di mejanya bersama dengan surat keluar yang perlu dia poskan.

Singkatnya:

  1. pertama, dia harus mengirim surat dan
  2. segera setelah itu selesai, dia perlu mencetak beberapa dokumen.

Fungsi panggilan balik adalah tugas kedua: mencetak dokumen-dokumen itu. Karena sudah selesai SETELAH surat dijatuhkan, dan juga karena catatan tempel yang menyuruhnya mencetak dokumen diberikan kepadanya beserta surat yang harus dia kirim.

Sekarang mari kita ikat ini dengan kosakata pemrograman

  • Nama metode dalam kasus ini adalah: DropOffMail.
  • Dan fungsi panggilan balik adalah: PrintOffDocuments. PrintOffDocuments adalah fungsi panggilan balik karena kami ingin sekretaris melakukan itu, hanya setelah DropOffMail berjalan.
  • Jadi saya akan "meneruskan: PrintOffDocuments sebagai" argumen "ke metode DropOffMail. Ini adalah poin penting.

Hanya itu saja. Tidak ada lagi. Saya harap ini menjelaskan bagi Anda - dan jika tidak, kirimkan komentar dan saya akan melakukan yang terbaik untuk mengklarifikasi.

BKSpurgeon
sumber
18

Ini membuat panggilan balik terdengar seperti pernyataan pengembalian di akhir metode.

Saya tidak yakin itulah mereka.

Saya pikir Callback sebenarnya adalah panggilan ke suatu fungsi, sebagai konsekuensi dari fungsi lain yang dipanggil dan diselesaikan.

Saya juga berpikir Callback dimaksudkan untuk mengatasi permohonan yang berasal, dalam semacam "hei! Hal yang Anda minta? Saya sudah melakukannya - hanya berpikir saya akan memberi tahu Anda - kembali kepada Anda".

Mauritico
sumber
1
+1 untuk mempertanyakan Callback vs Pernyataan pengembalian. Saya terbiasa dengan ini dan begitu banyak lulusan yang bekerja dengan saya.
8bitjunkie
2
Jawaban yang bagus - membantu saya memahaminya tidak seperti banyak jawaban lainnya!
adaam
18

Apa itu panggilan balik ?

  • Secara umum, panggilan telepon dilakukan untuk mengembalikan yang diterima seseorang.
  • Dalam komputasi, panggilan balik adalah bagian dari kode yang dapat dieksekusi yang dilewatkan sebagai argumen ke kode lain. Ketika fungsi selesai dengan pekerjaannya (atau ketika beberapa peristiwa terjadi), ia memanggil panggilan balik Anda (itu memanggil Anda kembali - karena itu namanya) berfungsi.

Apa itu fungsi callback ?

  • fungsi panggilan balik seperti seorang Hamba yang "memanggil kembali" ke tuannya ketika dia telah menyelesaikan tugas.
  • sebuah fungsi callback adalah fungsi yang dilewatkan ke fungsi lain (sebut fungsi ini lainnya otherFunction) sebagai parameter, dan fungsi callback disebut (atau dieksekusi) di dalam otherFunction.
    function action(x, y, callback) {
        return callback(x, y);
    }

    function multiplication(x, y) {
        return x * y;
    }

    function addition(x, y) {
        return x + y;
    }

    alert(action(10, 10, multiplication)); // output: 100

    alert(action(10, 10, addition)); // output: 20

Dalam SOA, panggilan balik memungkinkan Modul Plugin untuk mengakses layanan dari wadah / lingkungan.

Analogi: Callback. Tidak sinkron. Non-blocking
Contoh kehidupan nyata untuk panggilan balik

Premraj
sumber
Fungsi panggilan balik itu sendiri bukanlah fungsi tingkat tinggi. Ini diteruskan ke fungsi tingkat tinggi.
danio
17

Panggilan Setelah akan menjadi nama yang lebih baik daripada nama yang bodoh, panggilan balik . Ketika atau jika kondisi terpenuhi dalam suatu fungsi, panggil fungsi lain, fungsi Panggil Setelah , yang diterima sebagai argumen.

Daripada mengkodekan fungsi dalam fungsi, seseorang menulis fungsi untuk menerima fungsi Panggilan Setelah yang sudah ditulis sebagai argumen. The Panggilan Setelah mungkin dipanggil berdasarkan perubahan kondisi terdeteksi oleh kode dalam fungsi menerima argumen.

Pukulan MacDougal
sumber
Ini ide yang bagus. Saya pergi untuk "dipanggil di belakang" untuk mencoba menjelaskan ini. Saya bisa melihat seseorang seperti Martin Fowler mempopulerkan "panggilan setelah" sebagai istilah baru untuk ini di blog mani.
8bitjunkie
15

Fungsi panggilan balik adalah fungsi yang Anda tentukan untuk fungsi / metode yang ada, untuk dipanggil ketika suatu tindakan selesai, membutuhkan pemrosesan tambahan, dll.

Dalam Javascript, atau lebih khusus jQuery, misalnya, Anda dapat menentukan argumen panggilan balik yang akan dipanggil saat animasi selesai.

Dalam PHP, preg_replace_callback()fungsi ini memungkinkan Anda untuk menyediakan fungsi yang akan dipanggil ketika ekspresi reguler dicocokkan, melewati string yang cocok dengan argumen.

alex
sumber
10

lihat gambar :)begini Cara kerjanya

Program utama memanggil fungsi perpustakaan (yang mungkin juga merupakan fungsi level sistem) dengan nama fungsi panggilan balik. Fungsi panggilan balik ini mungkin diimplementasikan dalam beberapa cara. Program utama memilih satu panggilan balik sesuai kebutuhan.

Akhirnya, fungsi perpustakaan memanggil fungsi panggilan balik selama eksekusi.

Saumya Suhagiya
sumber
7
Maukah Anda menambahkan penjelasan teks untuk ini? Jika gambar hilang, jawaban ini kehilangan semua konteks.
Tim Post
teks dari orang lain menjelaskan yang terbaik. satu-satunya hal yang saya rasakan kurang adalah gambar :)
Dari semua deskripsi panjang lebar yang saya lihat di sini, ini adalah yang membuat saya berkata "ahhhhh, sekarang saya melihat penggunaannya." Dapatkan upvote.
DiBosco
7

Jawaban sederhana untuk pertanyaan ini adalah bahwa fungsi callback adalah fungsi yang dipanggil melalui pointer fungsi. Jika Anda melewatkan pointer (alamat) dari suatu fungsi sebagai argumen ke yang lain, ketika pointer itu digunakan untuk memanggil fungsi itu menunjuk ke sana dikatakan bahwa panggilan balik dilakukan

Zain Ali
sumber
6

Asumsikan kita memiliki fungsi di sort(int *arraytobesorted,void (*algorithmchosen)(void))mana ia dapat menerima pointer fungsi sebagai argumennya yang dapat digunakan di beberapa titik dalam sort()implementasi. Kemudian, di sini kode yang sedang ditangani oleh pointer fungsi algorithmchosendisebut sebagai fungsi callback .

Dan lihat kelebihannya adalah kita bisa memilih algoritma apa saja seperti:

  1.    algorithmchosen = bubblesort
  2.    algorithmchosen = heapsort
  3.    algorithmchosen = mergesort   ...

Yang, misalnya, telah diimplementasikan dengan prototipe:

  1.   `void bubblesort(void)`
  2.   `void heapsort(void)`
  3.   `void mergesort(void)`   ...

Ini adalah konsep yang digunakan dalam mencapai Polimorfisme dalam Pemrograman Berorientasi Objek

Neeraj
sumber
Penjelasan hebat di javascriptissexy.com/…; yang akan saya posting ulang di sini; Fungsi panggilan balik adalah fungsi yang diteruskan ke fungsi lain sebagai parameter, dan fungsi panggilan balik dipanggil atau dieksekusi di dalam Fungsi lainnya. // Perhatikan bahwa item dalam parameter metode klik adalah fungsi, bukan variabel. // Item tersebut adalah fungsi panggilan balik $ ("# btn_1"). Klik (function () {alert ("Btn 1 Clicked" );}); Seperti yang Anda lihat pada contoh sebelumnya, kami meneruskan fungsi sebagai parameter ke metode klik untuk dieksekusi -
MarcoZen
4

“Dalam pemrograman komputer, panggilan balik adalah referensi ke kode yang dapat dieksekusi, atau bagian dari kode yang dapat dieksekusi, yang diteruskan sebagai argumen ke kode lain. Ini memungkinkan lapisan perangkat lunak tingkat rendah untuk memanggil subrutin (atau fungsi) yang didefinisikan dalam lapisan tingkat yang lebih tinggi. " - Wikipedia

Callback di C menggunakan Function Pointer

Di C, callback diimplementasikan menggunakan Function Pointer. Function Pointer - seperti namanya, adalah penunjuk ke suatu fungsi.

Misalnya, int (* ptrFunc) ();

Di sini, ptrFunc adalah pointer ke fungsi yang tidak menggunakan argumen dan mengembalikan integer. JANGAN lupa untuk memasukkan tanda kurung, jika tidak kompiler akan menganggap bahwa ptrFunc adalah nama fungsi normal, yang tidak mengambil apa-apa dan mengembalikan pointer ke integer.

Berikut ini beberapa kode untuk mendemonstrasikan penunjuk fungsi.

#include<stdio.h>
int func(int, int);
int main(void)
{
    int result1,result2;
    /* declaring a pointer to a function which takes
       two int arguments and returns an integer as result */
    int (*ptrFunc)(int,int);

    /* assigning ptrFunc to func's address */                    
    ptrFunc=func;

    /* calling func() through explicit dereference */
    result1 = (*ptrFunc)(10,20);

    /* calling func() through implicit dereference */        
    result2 = ptrFunc(10,20);            
    printf("result1 = %d result2 = %d\n",result1,result2);
    return 0;
}

int func(int x, int y)
{
    return x+y;
}

Sekarang mari kita mencoba memahami konsep Callback di C menggunakan pointer fungsi.

Program lengkap memiliki tiga file: callback.c, reg_callback.h dan reg_callback.c.

/* callback.c */
#include<stdio.h>
#include"reg_callback.h"

/* callback function definition goes here */
void my_callback(void)
{
    printf("inside my_callback\n");
}

int main(void)
{
    /* initialize function pointer to
    my_callback */
    callback ptr_my_callback=my_callback;                        
    printf("This is a program demonstrating function callback\n");
    /* register our callback function */
    register_callback(ptr_my_callback);                          
    printf("back inside main program\n");
    return 0;
}

/* reg_callback.h */
typedef void (*callback)(void);
void register_callback(callback ptr_reg_callback);


/* reg_callback.c */
#include<stdio.h>
#include"reg_callback.h"

/* registration goes here */
void register_callback(callback ptr_reg_callback)
{
    printf("inside register_callback\n");
    /* calling our callback function my_callback */
    (*ptr_reg_callback)();                               
}

Jika kita menjalankan program ini, hasilnya akan menjadi

Ini adalah program yang menunjukkan fungsi callback di dalam register_callback di dalam my_callback kembali ke dalam program utama

Fungsi lapisan yang lebih tinggi memanggil fungsi lapisan bawah sebagai panggilan normal dan mekanisme panggilan balik memungkinkan fungsi lapisan bawah untuk memanggil fungsi lapisan yang lebih tinggi melalui penunjuk ke fungsi panggilan balik.

Callback di Java Menggunakan Antarmuka

Java tidak memiliki konsep pointer fungsi. Ia mengimplementasikan mekanisme Callback melalui mekanisme Interface-nya. Di sini alih-alih pointer fungsi, kami mendeklarasikan sebuah Interface yang memiliki metode yang akan dipanggil ketika callee menyelesaikan tugasnya.

Izinkan saya menunjukkannya melalui contoh:

Antarmuka Panggilan Balik

public interface Callback
{
    public void notify(Result result);
}

Penelepon atau Kelas Tingkat Tinggi

public Class Caller implements Callback
{
Callee ce = new Callee(this); //pass self to the callee

//Other functionality
//Call the Asynctask
ce.doAsynctask();

public void notify(Result result){
//Got the result after the callee has finished the task
//Can do whatever i want with the result
}
}

Fungsi Callee atau lapisan bawah

public Class Callee {
Callback cb;
Callee(Callback cb){
this.cb = cb;
}

doAsynctask(){
//do the long running task
//get the result
cb.notify(result);//after the task is completed, notify the caller
}
}

Callback Menggunakan pola EventListener

  • Daftar barang

Pola ini digunakan untuk memberi tahu 0 hingga n jumlah Pengamat / Pendengar bahwa tugas tertentu telah selesai

  • Daftar barang

Perbedaan antara mekanisme Callback dan mekanisme EventListener / Observer adalah bahwa dalam callback, callee memberi tahu penelepon tunggal, sedangkan di Eventlisener / Observer, callee dapat memberi tahu siapa pun yang tertarik dengan peristiwa itu (notifikasi dapat pergi ke beberapa bagian lain dari aplikasi yang belum memicu tugas)

Izinkan saya menjelaskannya melalui contoh.

Antarmuka Acara

public interface Events {

public void clickEvent();
public void longClickEvent();
}

Widget kelas

package com.som_itsolutions.training.java.exampleeventlistener;

import java.util.ArrayList;
import java.util.Iterator;

public class Widget implements Events{

    ArrayList<OnClickEventListener> mClickEventListener = new ArrayList<OnClickEventListener>(); 
    ArrayList<OnLongClickEventListener> mLongClickEventListener = new ArrayList<OnLongClickEventListener>();

    @Override
    public void clickEvent() {
        // TODO Auto-generated method stub
        Iterator<OnClickEventListener> it = mClickEventListener.iterator();
                while(it.hasNext()){
                    OnClickEventListener li = it.next();
                    li.onClick(this);
                }   
    }
    @Override
    public void longClickEvent() {
        // TODO Auto-generated method stub
        Iterator<OnLongClickEventListener> it = mLongClickEventListener.iterator();
        while(it.hasNext()){
            OnLongClickEventListener li = it.next();
            li.onLongClick(this);
        }

    }

    public interface OnClickEventListener
    {
        public void onClick (Widget source);
    }

    public interface OnLongClickEventListener
    {
        public void onLongClick (Widget source);
    }

    public void setOnClickEventListner(OnClickEventListener li){
        mClickEventListener.add(li);
    }
    public void setOnLongClickEventListner(OnLongClickEventListener li){
        mLongClickEventListener.add(li);
    }
}

Tombol Kelas

public class Button extends Widget{
private String mButtonText;
public Button (){
} 
public String getButtonText() {
return mButtonText;
}
public void setButtonText(String buttonText) {
this.mButtonText = buttonText;
}
}

Kotak centang kelas

public class CheckBox extends Widget{
private boolean checked;
public CheckBox() {
checked = false;
}
public boolean isChecked(){
return (checked == true);
}
public void setCheck(boolean checked){
this.checked = checked;
}
}

Kelas Kegiatan

package com.som_itsolutions.training.java.exampleeventlistener;

public class Activity implements Widget.OnClickEventListener
{
    public Button mButton;
    public CheckBox mCheckBox;
    private static Activity mActivityHandler;
    public static Activity getActivityHandle(){
        return mActivityHandler;
    }
    public Activity ()
    {
        mActivityHandler = this;
        mButton = new Button();
        mButton.setOnClickEventListner(this);
        mCheckBox = new CheckBox();
        mCheckBox.setOnClickEventListner(this);
        } 
    public void onClick (Widget source)
    {
        if(source == mButton){
            mButton.setButtonText("Thank you for clicking me...");
            System.out.println(((Button) mButton).getButtonText());
        }
        if(source == mCheckBox){
            if(mCheckBox.isChecked()==false){
                mCheckBox.setCheck(true);
                System.out.println("The checkbox is checked...");
            }
            else{
                mCheckBox.setCheck(false);
                System.out.println("The checkbox is not checked...");
            }       
        }
    }
    public void doSomeWork(Widget source){
        source.clickEvent();
    }   
}

Kelas Lainnya

public class OtherClass implements Widget.OnClickEventListener{
Button mButton;
public OtherClass(){
mButton = Activity.getActivityHandle().mButton;
mButton.setOnClickEventListner(this);//interested in the click event                        //of the button
}
@Override
public void onClick(Widget source) {
if(source == mButton){
System.out.println("Other Class has also received the event notification...");
}
}

Kelas Utama

public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Activity a = new Activity();
OtherClass o = new OtherClass();
a.doSomeWork(a.mButton);
a.doSomeWork(a.mCheckBox);
}
}

Seperti yang dapat Anda lihat dari kode di atas, bahwa kami memiliki antarmuka yang disebut peristiwa yang pada dasarnya mencantumkan semua peristiwa yang mungkin terjadi untuk aplikasi kami. Kelas Widget adalah kelas dasar untuk semua komponen UI seperti Tombol, Kotak Centang. Komponen UI ini adalah objek yang benar-benar menerima peristiwa dari kode kerangka kerja. Kelas widget mengimplementasikan antarmuka Acara dan juga memiliki dua antarmuka bersarang yaitu OnClickEventListener & OnLongClickEventListener

Kedua antarmuka ini bertanggung jawab untuk mendengarkan acara yang mungkin terjadi pada komponen UI yang diturunkan dari Widget seperti Tombol atau Kotak Centang. Jadi jika kita membandingkan contoh ini dengan contoh Callback sebelumnya menggunakan Java Interface, kedua antarmuka ini berfungsi sebagai antarmuka Callback. Jadi kode tingkat yang lebih tinggi (Aktivitas Di Sini) mengimplementasikan dua antarmuka ini. Dan setiap kali suatu peristiwa terjadi pada widget, kode tingkat yang lebih tinggi (atau metode antarmuka ini diimplementasikan dalam kode tingkat yang lebih tinggi, yang ada di sini Kegiatan) akan dipanggil.

Sekarang saya akan membahas perbedaan mendasar antara pola Callback dan Eventlistener. Seperti yang telah kami sebutkan bahwa menggunakan Callback, Callee hanya dapat memberi tahu Penelepon tunggal. Tetapi dalam kasus pola EventListener, setiap bagian atau kelas Aplikasi dapat mendaftar untuk acara yang mungkin terjadi pada Tombol atau Kotak Centang. Contoh kelas semacam ini adalah OtherClass. Jika Anda melihat kode OtherClass, Anda akan mendapati bahwa kode itu telah terdaftar sebagai pendengar ClickEvent yang mungkin muncul di Tombol yang ditentukan dalam Kegiatan. Bagian yang menarik adalah bahwa, di samping Activity (Penelepon), OtherClass ini juga akan diberitahukan setiap kali klik terjadi pada Button.

somenath mukhopadhyay
sumber
Harap hindari hanya tautan jawaban . Jawaban yang "tidak lebih dari tautan ke situs eksternal" dapat dihapus .
Quentin
3

Fungsi panggilan balik adalah fungsi yang Anda berikan (sebagai referensi atau pointer) ke fungsi atau objek tertentu. Fungsi atau objek ini akan memanggil fungsi ini kembali kapan saja, mungkin beberapa kali, untuk tujuan apa pun:

  • memberi tahu akhir tugas
  • meminta perbandingan antara dua item (seperti dalam c qsort ())
  • melaporkan kemajuan suatu proses
  • memberitahukan acara
  • mendelegasikan instansi objek
  • mendelegasikan lukisan suatu daerah

...

Jadi menggambarkan panggilan balik sebagai fungsi yang dipanggil di akhir fungsi atau tugas lain terlalu menyederhanakan (bahkan jika itu adalah kasus penggunaan umum).

XouDo
sumber
2

Panggilan balik adalah gagasan untuk meneruskan fungsi sebagai parameter ke fungsi lain dan meminta fungsi ini dipanggil setelah prosesnya selesai.

Jika Anda mendapatkan konsep panggilan balik melalui jawaban luar biasa di atas, saya sarankan Anda harus mempelajari latar belakang idenya.

"Apa yang membuat mereka (Ilmuwan Komputer) mengembangkan panggilan balik?" Anda mungkin belajar masalah, yaitu pemblokiran. (Terutama pemblokiran UI) Dan panggilan balik bukan satu-satunya solusi untuk itu. Ada banyak solusi lain (mis: Utas, Berjangka, Janji ...).

Yoji Yamamoto
sumber
1

Satu area penggunaan penting adalah Anda mendaftarkan salah satu fungsi Anda sebagai pegangan (yaitu panggilan balik) dan kemudian mengirim pesan / memanggil beberapa fungsi untuk melakukan pekerjaan atau pemrosesan. Sekarang setelah pemrosesan selesai, fungsi yang dipanggil akan memanggil fungsi terdaftar kami (yaitu sekarang panggil kembali dilakukan), yang mengindikasikan bahwa kami memproses selesai. Tautan wikipedia
ini menjelaskan grafik dengan cukup baik.

Chintan Parikh
sumber
1

Fungsi panggilan balik, juga dikenal sebagai fungsi tingkat tinggi, adalah fungsi yang diteruskan ke fungsi lain sebagai parameter, dan fungsi panggilan balik disebut (atau dieksekusi) di dalam fungsi induk.

$("#button_1").click(function() {
  alert("button 1 Clicked");
});

Di sini kita telah melewati fungsi sebagai parameter ke metode klik. Dan metode klik akan memanggil (atau menjalankan) fungsi panggilan balik yang kami berikan.

chirag20388
sumber
1
Fungsi panggilan balik itu sendiri bukanlah fungsi tingkat tinggi. Ini diteruskan ke fungsi tingkat tinggi.
danio
1

Fungsi Panggilan Balik Fungsi yang dialihkan ke fungsi lain sebagai argumen.

function test_function(){       
 alert("Hello world");  
} 

setTimeout(test_function, 2000);

Catatan: Dalam contoh di atas test_function digunakan sebagai argumen untuk fungsi setTimeout.

Garvin
sumber
1
Selamat Datang di Stack Overflow! Sebelum menjawab pertanyaan, selalu baca jawaban yang ada. Jawaban ini sudah disediakan. Alih-alih mengulangi jawabannya, pilih jawaban yang ada. Beberapa pedoman untuk menulis jawaban yang baik dapat ditemukan di sini .
dferenc