[Function] كيف نفسر الاستدعاءات في الانجليزية عادي؟ كيف تختلف عن استدعاء وظيفة واحدة من وظيفة أخرى؟



Answers

سأحاول أن أبقي هذا ميتا بسيطا. "رد الاتصال" هو أي دالة يتم استدعاؤها بواسطة وظيفة أخرى تأخذ الوظيفة الأولى كمعلمة. في كثير من الأحيان ، تكون "معاودة الاتصال" دالة تسمى عندما يحدث شيء ما . يمكن تسمية هذا الشيء بـ "حدث" في مبرمج الكلام.

تخيل هذا السيناريو: أنت تتوقع حزمة في غضون يومين. الحزمة هي هدية لجارتك. لذلك ، بمجرد حصولك على الحزمة ، فإنك ترغب في جلبها إلى الجيران. أنت خارج المدينة ، لذا تركت تعليمات لزوجك.

يمكنك إخبارهم بالحصول على الحزمة وإحضارها إلى الجيران. إذا كان زوجك غبيًا كجهاز كمبيوتر ، فسوف يجلس على الباب وينتظر الطرد حتى يأتي (لا يفعل أي شيء آخر) وبعد ذلك سيأتي به إلى الجيران. لكن هناك طريقة أفضل. أخبر زوجتك أنه بمجرد حصولهم على العبوة ، يجب عليهم إحضارها على الجيران. بعد ذلك ، يمكن أن يذهبون للحياة عادة حتى يتلقوا الحزمة.

في مثالنا ، فإن استلام الحزمة هو "الحدث" وإحضاره إلى الجيران هو "معاودة الاتصال". تقوم زوجتك "بتشغيل" تعليماتك لإحضار الحزمة فقط عندما تصل الحزمة. أفضل بكثير!

هذا النوع من التفكير واضح في الحياة اليومية ، لكن أجهزة الكمبيوتر لا تملك نفس النوع من الحس السليم. فكر كيف يكتب المبرمجون عادةً إلى ملف:

fileObject = open(file)
# now that we have WAITED for the file to open, we can write to it
fileObject.write("We are writing to the file.")
# now we can continue doing the other, totally unrelated things our program does

هنا ، ننتظر فتح الملف ، قبل أن نكتب إليه. هذا "يمنع" تدفق التنفيذ ، ولا يستطيع برنامجنا القيام بأي من الأشياء الأخرى التي قد يحتاج إليها! ماذا لو استطعنا القيام بذلك بدلاً من ذلك:

# we pass writeToFile (A CALLBACK FUNCTION!) to the open function
fileObject = open(file, writeToFile)
# execution continues flowing -- we don't wait for the file to be opened
# ONCE the file is opened we write to it, but while we wait WE CAN DO OTHER THINGS!

اتضح أننا نفعل ذلك مع بعض اللغات والأطر. إنه رائع! تحقق من Node.js للحصول على بعض الممارسة الحقيقية مع هذا النوع من التفكير.

Question

كيف نفسر الاستدعاءات باللغة الانجليزية البسيطة؟ كيف تختلف عن استدعاء وظيفة واحدة من وظيفة أخرى تأخذ بعض السياق من وظيفة الاستدعاء؟ كيف يمكن شرح قوتهم لمبرمج مبتدئ؟




“In computer programming, a callback is a reference to executable code, or a piece of executable code, that is passed as an argument to other code. This allows a lower-level software layer to call a subroutine (or function) defined in a higher-level layer.” - Wikipedia

Callback in C using Function Pointer

In C, callback is implemented using Function Pointer. Function Pointer - as the name suggests, is a pointer to a function.

For example, int (*ptrFunc) ();

Here, ptrFunc is a pointer to a function that takes no arguments and returns an integer. DO NOT forget to put in the parenthesis, otherwise the compiler will assume that ptrFunc is a normal function name, which takes nothing and returns a pointer to an integer.

Here is some code to demonstrate the function pointer.

#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;
}

Now let us try to understand the concept of Callback in C using function pointer.

The complete program has three files: callback.c, reg_callback.h and 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)();                               
}

If we run this program, the output will be

This is a program demonstrating function callback inside register_callback inside my_callback back inside main program

The higher layer function calls a lower layer function as a normal call and the callback mechanism allows the lower layer function to call the higher layer function through a pointer to a callback function.

Callback in Java Using Interface

Java does not have the concept of function pointer It implements Callback mechanism through its Interface mechanism Here instead of a function pointer, we declare an Interface having a method which will be called when the callee finishes its task

Let me demonstrate it through an example:

The Callback Interface

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

The Caller or the Higher Level Class

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
}
}

The Callee or the lower layer function

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 Using EventListener pattern

  • قائمة الاغراض

This pattern is used to notify 0 to n numbers of Observers/Listeners that a particular task has finished

  • قائمة الاغراض

The difference between Callback mechanism and EventListener/Observer mechanism is that in callback, the callee notifies the single caller, whereas in Eventlisener/Observer, the callee can notify anyone who is interested in that event (the notification may go to some other parts of the application which has not triggered the task)

Let me explain it through an example.

The Event Interface

public interface Events {

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

Class Widget

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);
    }
}

Class Button

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

Class Checkbox

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;
}
}

Activity Class

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();
    }   
}

Other Class

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...");
}
}

Main Class

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);
}
}

As you can see from the above code, that we have an interface called events which basically lists all the events that may happen for our application. The Widget class is the base class for all the UI components like Button, Checkbox. These UI components are the objects that actually receive the events from the framework code. Widget class implements the Events interface and also it has two nested interfaces namely OnClickEventListener & OnLongClickEventListener

These two interfaces are responsible for listening to events that may occur on the Widget derived UI components like Button or Checkbox. So if we compare this example with the earlier Callback example using Java Interface, these two interfaces work as the Callback interface. So the higher level code (Here Activity) implements these two interfaces. And whenever an event occurs to a widget, the higher level code (or the method of these interfaces implemented in the higher level code, which is here Activity) will be called.

Now let me discuss the basic difference between Callback and Eventlistener pattern. As we have mentioned that using Callback, the Callee can notify only a single Caller. But in the case of EventListener pattern, any other part or class of the Application can register for the events that may occur on the Button or Checkbox. The example of this kind of class is the OtherClass. If you see the code of the OtherClass, you will find that it has registered itself as a listener to the ClickEvent that may occur in the Button defined in the Activity. Interesting part is that, besides the Activity ( the Caller), this OtherClass will also be notified whenever the click event occurs on the Button.




In plain english a callback is a promise. Joe, Jane, David and Samantha share a carpool to work. Joe is driving today. Jane, David and Samantha have a couple of options:

  1. Check the window every 5 minutes to see if Joe is out
  2. Keep doing their thing until Joe rings the door bell.

Option 1: This is more like a polling example where Jane would be stuck in a "loop" checking if Joe is outside. Jane can't do anything else in the mean time.

Option 2: This is the callback example. Jane tells Joe to ring her doorbell when he's outside. She gives him a "function" to ring the door bell. Joe does not need to know how the door bell works or where it is, he just needs to call that function ie ring the door bell when he's there.

Callbacks are driven by "events". In this example the "event" is Joe's arrival. In Ajax for example events can be "success" or "failure" of the asynchronous request and each can have the same or different callbacks.

In terms of JavaScript applications and callbacks. We also need to understand "closures" and application context. What "this" refers to can easily confuse JavaScript developers. In this example within each person's "ring_the_door_bell()" method/callback there might be some other methods that each person need to do based on their morning routine ex. "turn_off_the_tv()". We would want "this" to refer to the "Jane" object or the "David" object so that each can setup whatever else they need done before Joe picks them up. This is where setting up the callback with Joe requires parodying the method so that "this" refers to the right object.

Hope that helps!




هناك نقطتان يجب شرحهما ، إحداهما هي كيفية عمل الاستدعاء (يمر حول دالة يمكن استدعاؤها بدون أي معرفة بسياقها) ، والآخر ما يتم استخدامه (التعامل مع الأحداث بشكل غير متزامن).

إن التشبيه بانتظار وصول الطرد الذي تم استخدامه بواسطة إجابات أخرى هو أمر جيد لشرح كليهما. في برنامج الكمبيوتر ، ستخبر الكمبيوتر أن يتوقع طردًا. عادة ، يجلس الآن هناك وينتظر (ولا يفعل شيئاً آخر) حتى يصل الطرد ، ربما إلى أجل غير مسمى إذا لم يصل أبداً. بالنسبة إلى البشر ، يبدو هذا الأمر سخيفًا ، لكن دون اتخاذ مزيد من الإجراءات ، يعد هذا أمرًا طبيعيًا تمامًا بالنسبة للكمبيوتر.

الآن سيكون رد الاتصال هو الجرس عند باب منزلك. أنت تقدم خدمة الطرود بطريقة لإعلامك بوصول الطرود دون الحاجة إلى معرفة أين (إذا كنت) في المنزل ، أو كيفية عمل الجرس. (على سبيل المثال ، تقوم بعض "الأجراس" في الواقع بإرسال مكالمة هاتفية.) لأنك قدمت "وظيفة رد اتصال" يمكن "استدعاء" في أي وقت ، خارج السياق ، يمكنك الآن التوقف عن الجلوس في الشرفة الأمامية و "التعامل مع حدث "(من وصول الطرود) كلما حان الوقت.




Think of a method as giving a task to a coworker. A simple task might be the following:

Solve these equations:
x + 2 = y
2 * x = 3 * y

Your coworker diligently does the math and gives you the following result:

x = -6
y = -4

But your coworker has a problem, he doesn't always understand notations, such as ^ , but he does understand them by their description. Such as exponent . Everytime he finds one of these you get back the following:

I don't understand "^"

This requires you to rewrite your entire instruction set again after explaining what the character means to your coworker, and he doesn't always remember in between questions. And he has difficulty remembering your tips as well, such as just ask me. He always follows your written directions as best he can however.

You think of a solution, you just add the following to all of your instructions:

If you have any questions about symbols, call me at extension 1234 and I will tell you its name.

Now whenever he has a problem he calls you and asks, rather than giving you a bad response and making the process restart.




This of it in terms of downloading a webpage:

Your program runs on a cellphone and is requesting the webpage http://www.google.com . If you write your program synchronously, the function you write to download the data will be running continuously until all the data is download. This means your UI will not refresh and will basically appear frozen. If you write your program using callbacks, you request the data and say "execute this function when you've finished." This allows the UI to still allow user interaction while the file is downloading. Once the webpage has finished downloading, your result function (callback) is called and you can handle the data.

في الأساس ، يسمح لك بطلب شيء ومتابعة التنفيذ أثناء انتظار النتيجة. بمجرد أن تعود النتيجة إليك عبر وظيفة رد اتصال ، يمكنك التقاط العملية التي توقفت عندها.




دعنا نتظاهر بأنك كنت ستعطيني مهمة طويلة المدى: احصل على أسماء الأشخاص الخمسة الفريدين الأوائل الذين صادفتهم. قد يستغرق هذا الأمر أيامًا إذا كنت في منطقة ذات كثافة سكانية منخفضة. أنت لست مهتمًا حقًا بالجلوس على يديك أثناء الجري حتى تقول: "عندما تكون لديك القائمة ، اتصل بي على زنزانتي وقراءتها إليّ. إليك الرقم".

لقد أعطيتني مرجع رد - وهي وظيفة من المفترض أن أقوم بتنفيذها لتسليم مزيد من المعالجة.

في جافا سكريبت ، قد يبدو الأمر كالتالي:

var lottoNumbers = [];
var callback = function(theNames) {
  for (var i=0; i<theNames.length; i++) {
    lottoNumbers.push(theNames[i].length);
  }
};

db.executeQuery("SELECT name " +
                "FROM tblEveryOneInTheWholeWorld " +
                "ORDER BY proximity DESC " +
                "LIMIT 5", callback);

while (lottoNumbers.length < 5) {
  playGolf();
}
playLotto(lottoNumbers);

ربما يمكن تحسين ذلك بطرق كثيرة. على سبيل المثال ، يمكنك توفير معاودة اتصال ثانية: إذا استغرق الأمر وقتًا أطول من ساعة ، فاتصل بالهاتف الأحمر وأخبر الشخص الذي أجاب أنك قد انتهت مهلته.




Plain and simple: A callback is a function that you give to another function, so that it can call it.

Usually it is called when some operation is completed. Since you create the callback before giving it to the other function, you can initialize it with context information from the call site. That is why it is named a call*back* - the first function calls back into the context from where it was called.




لديك بعض الرموز التي تريد تشغيلها. عادةً ، عندما تسميها ، فإنك تنتظر الانتهاء منها قبل الاستمرار (مما قد يتسبب في تحول تطبيقك إلى اللون الرمادي / إنتاج وقت دوران للمؤشر).

هناك طريقة بديلة لتشغيل هذا الرمز بالتوازي والاستمرار في عملك. ولكن ماذا لو احتاجت الشفرة الأصلية إلى القيام بأشياء مختلفة بناءً على الاستجابة من الرمز الذي يطلق عليه؟ حسنًا ، في هذه الحالة ، يمكنك تمرير اسم / موقع الرمز الذي تريد الاتصال به عند الانتهاء من ذلك. هذا هو "معاودة الاتصال".

الرمز الطبيعي: اسأل عن المعلومات-> معلومات العملية-> تعامل مع نتائج المعالجة-> استمر في القيام بأشياء أخرى.

مع الاستدعاءات: اسأل عن المعلومات-> معلومات العملية-> مواصلة القيام بأشياء أخرى. وفي نقطة لاحقة-> تعامل مع نتائج المعالجة.




تفسير مجازي:

لدي طرد أريد توصيله إلى صديق ، وأريد أيضًا أن أعرف متى يتلقى صديقي ذلك.

لذا ، أحمل الطرد إلى مكتب البريد واطلب منهم تسليمه. إذا كنت أريد أن أعرف عندما يتلقى صديقي الطرد ، لدي خياران:

(أ) يمكنني الانتظار في مكتب البريد حتى يتم تسليمه.

(ب) سأتلقى بريدًا إلكترونيًا عند تسليمه.

الخيار (ب) مماثل لاستدعاء.




يحتاج Johny مبرمج إلى دباسة ، لذلك يذهب إلى قسم الإمداد بالمكتب ويطلب واحد ، بعد ملئ نموذج الطلب هو يمكن أن يقف هناك وينتظر أن يذهب الكاتب ينظر حول المستودع لأجل الدباسة (مثل استدعاء وظيفة حجب ) أو الذهاب إلى القيام بشيء آخر في هذه الأثناء.

نظرًا لأن هذا يستغرق وقتًا طويلاً ، يضع جوني ملاحظة مع نموذج الطلب يطلب منه الاتصال به عندما تكون وحدة الدباسة جاهزة للاستلام ، حتى إنه في هذه الأثناء يمكنه أن يفعل شيئًا آخر مثل القيلولة على مكتبه.




What Is a Callback Function?

The simple answer to this first question is that a callback function is a function that is called through a function pointer. If you pass the pointer (address) of a function as an argument to another, when that pointer is used to call the function it points to it is said that a call back is made.

Callback function is hard to trace, but sometimes it is very useful. Especially when you are designing libraries. Callback function is like asking your user to gives you a function name, and you will call that function under certain condition.

For example, you write a callback timer. It allows you to specified the duration and what function to call, and the function will be callback accordingly. “Run myfunction() every 10 seconds for 5 times”

Or you can create a function directory, passing a list of function name and ask the library to callback accordingly. “Callback success() if success, callback fail() if failed.”

Lets look at a simple function pointer example

void cbfunc()
{
     printf("called");
}

 int main ()
 {
                   /* function pointer */ 
      void (*callback)(void); 
                   /* point to your callback function */ 
      callback=(void *)cbfunc; 
                   /* perform callback */
      callback();
      return 0; 
}

How to pass argument to callback function?

Observered that function pointer to implement callback takes in void *, which indicates that it can takes in any type of variable including structure. Therefore you can pass in multiple arguments by structure.

typedef struct myst
{
     int a;
     char b[10];
}myst;

void cbfunc(myst *mt) 
{
     fprintf(stdout,"called %d %s.",mt->a,mt->b); 
}

int main() 
{
       /* func pointer */
    void (*callback)(void *);       //param
     myst m;
     m.a=10;
     strcpy(m.b,"123");       
     callback = (void*)cbfunc;    /* point to callback function */
     callback(&m);                /* perform callback and pass in the param */
     return 0;   
}



يتم وصف عمليات رد الاتصال بسهولة من حيث نظام الهاتف. تتشابه المكالمة الوظيفية مع استدعاء شخص ما عبر الهاتف ، وتطلب منه سؤالاً ، والحصول على إجابة ، وتعليق ؛ تؤدي إضافة معاودة الاتصال إلى تغيير القياس بحيث أنه بعد طرح سؤال عليها ، ستعطيها أيضًا اسمك ورقمك حتى تتمكن من الاتصال بك مرة أخرى باستخدام الإجابة. - Paul Jakubik، "Callback Implementations in C ++"




أنا مندهش لرؤية العديد من الأشخاص الأذكياء يفشلون في التأكيد على حقيقة أن كلمة "رد الاتصال" أصبحت تستخدم بطريقتين متناقضتين.

يتضمن كلا الطريقتين تخصيص وظيفة بتمرير وظيفة إضافية (تعريف دالة ، مجهول أو مسمى) إلى وظيفة موجودة. أي.

customizableFunc(customFunctionality)

إذا تم توصيل الوظيفة المخصصة ببساطة في كتلة التعليمات البرمجية ، فقد قمت بتخصيص الوظيفة ، مثل ذلك.

    customizableFucn(customFunctionality) {
      var data = doSomthing();
      customFunctionality(data);
      ...
    }

على الرغم من أن هذا النوع من الوظائف المحقونة يسمى عادة "callback" ، فلا يوجد شيء يعتمد على ذلك. مثال واضح جداً هو أسلوب forEach الذي يتم فيه توفير دالة مخصصة كوسيطة ليتم تطبيقها على كل عنصر في صفيف لتعديل المصفوفة.

ولكن هذا يختلف بشكل أساسي عن استخدام وظائف "رد الاتصال" للبرمجة غير المتزامنة ، كما هو الحال في AJAX أو node.js أو ببساطة في تعيين وظائف لأحداث تفاعل المستخدم (مثل نقرات الماوس). في هذه الحالة ، تكون الفكرة بأكملها هي انتظار حدوث حدث طارئ قبل تنفيذ الوظيفة المخصصة. وهذا واضح في حالة تفاعل المستخدم ، ولكنه مهم أيضًا في عمليات الإدخال / الإخراج (i / o) التي يمكن أن تستغرق وقتًا ، مثل قراءة الملفات من القرص. هذا هو المكان الذي يجعل التعبير "callback" أكثر وضوحًا. بمجرد بدء عملية الإدخال / الإخراج (مثل طلب ملف ليتم قراءته من القرص أو الخادم لإرجاع البيانات من طلب http) ، لا ينتظر برنامج غير متزامن حتى ينتهي. يمكن المضي قدمًا في أي مهام مجدولة بعد ذلك ، والاستجابة فقط مع الوظيفة المخصصة بعد أن يتم إعلامك بأن ملف القراءة أو طلب http مكتمل (أو أنه فشل) وأن البيانات متاحة للوظيفة المخصصة. الأمر يشبه الاتصال بنشاط تجاري على الهاتف وترك رقم "رد الاتصال" ، حتى يتمكن من الاتصال بك عندما يكون هناك شخص متاح لك للرد عليك. هذا أفضل من معلقة على الخط لمن يعرف متى وعدم القدرة على حضور الشؤون الأخرى.

الاستخدام غير المتزامن ينطوي بطبيعته على بعض وسائل الاستماع للحدث المطلوب (على سبيل المثال ، إكمال عملية i / o) بحيث ، عندما تحدث (وفقط عندما تحدث) يتم تنفيذ وظيفة "callback" المخصصة. في مثال AJAX الواضح ، عندما تصل البيانات فعليًا من الخادم ، يتم تشغيل وظيفة "رد الاتصال" لاستخدام هذه البيانات لتعديل DOM ، وبالتالي إعادة رسم نافذة المتصفح إلى هذا الحد.

إلى خلاصة. يستخدم بعض الأشخاص الكلمة "callback" للإشارة إلى أي نوع من الوظائف المخصصة التي يمكن حقنها في وظيفة موجودة كوسيطة. ولكن ، على الأقل بالنسبة لي ، فإن الاستخدام الأكثر ملاءمة للكلمة هو حيث يتم استخدام وظيفة "رد الاتصال" المحقونة بشكل غير متزامن - ليتم تنفيذها فقط عند وقوع حدث ينتظر أن يتم إخطاره.




تخيل أنك تحتاج إلى دالة تقوم بإرجاع 10 مربعات بحيث تكتب دالة:

function tenSquared() {return 10*10;}

في وقت لاحق تحتاج إلى 9 مربع حتى تكتب وظيفة أخرى:

function nineSquared() {return 9*9;}

في النهاية ، ستستبدل كل هذه الوظائف بوظيفة عامة:

function square(x) {return x*x;}

ينطبق التفكير نفسه بالضبط على عمليات الرد. لديك وظيفة تقوم بشيء ما وعند إجراء مكالمات doA:

function computeA(){
    ...
    doA(result);
}

في وقت لاحق تريد نفس الوظيفة لاستدعاء doB بدلاً من ذلك يمكنك تكرار الوظيفة بأكملها:

function computeB(){
    ...
    doB(result);
}

أو يمكنك تمرير وظيفة رد اتصال كمتغير ويجب أن يكون لديك الوظيفة مرة واحدة فقط:

function compute(callback){
    ...
    callback(result);
}

ثم عليك فقط استدعاء الحوسبة (DoA) وحساب (doB).

أبعد من تبسيط التعليمات البرمجية ، فإنه يتيح لك رمز غير متزامن معرفة أنك قد أكملت عن طريق استدعاء الوظيفة التعسفية الخاصة بك عند الانتهاء ، على غرار عندما تتصل شخص ما على الهاتف وترك رقم رد اتصال.




Links