[function] 일반 영어로 콜백을 설명하는 방법? 한 함수를 다른 함수에서 호출하는 것과 어떻게 다른가요?

일반 영어로 콜백을 설명하는 방법은 무엇입니까? 호출 함수의 컨텍스트를 사용하여 한 함수를 다른 함수에서 호출하는 것과 어떻게 다릅니 까? 초보자 프로그래머에게 그들의 힘을 어떻게 설명 할 수 있습니까?



답변

종종 응용 프로그램은 컨텍스트 / 상태에 따라 다른 기능을 실행해야합니다. 이를 위해 호출 할 함수에 대한 정보를 저장할 변수를 사용합니다. need 필요에 따라 응용 프로그램은 호출 할 함수에 대한 정보를 사용하여이 변수를 설정하고 동일한 변수를 사용하여 함수를 호출합니다.

자바 스크립트에서 예제는 다음과 같습니다. 여기서 함수에 대한 정보를 저장하는 변수로 메소드 인수를 사용합니다.

function processArray(arr, callback) {
    var resultArr = new Array();
    for (var i = arr.length-1; i >= 0; i--)
        resultArr[i] = callback(arr[i]);
    return resultArr;
}

var arr = [1, 2, 3, 4];
var arrReturned = processArray(arr, function(arg) {return arg * -1;});
// arrReturned would be [-1, -2, -3, -4]


답변

나는이 죽은 것을 단순하게 유지하려고 노력할 것입니다. “콜백”은 첫 번째 함수를 매개 변수로 사용하는 다른 함수에 의해 호출되는 함수입니다. 많은 경우 “콜백”은 무언가 가 발생할 때 호출되는 함수입니다 . 그 무언가는 프로그래머 발언에서 “이벤트”를 호출 할 수 있습니다.

이 시나리오를 상상해보십시오. 며칠 안에 패키지를 예상하고 있습니다. 패키지는 이웃을위한 선물입니다. 따라서 일단 패키지를 받으면 이웃에게 가져 오기를 원합니다. 당신은 도시를 벗어 났으므로 배우자에게 지시 사항을 남깁니다.

패키지를 가져와 이웃에게 가져 오라고 할 수 있습니다. 배우자가 컴퓨터만큼 어리석은 경우, 문 앞에 앉아 패키지가 올 때까지 기다렸다가 (아무것도하지 말고) 한 번 들어 오면 이웃에게 가져다 줄 것입니다. 그러나 더 좋은 방법이 있습니다. 배우자에게 패키지를받은 후 이웃에게 가져 가야한다고 말하십시오. 그런 다음 패키지를받을 때까지 정상적으로 생활 할 수 있습니다.

이 예에서 패키지 수신은 “이벤트”이고 이웃에게 가져 오는 것은 “콜백”입니다. 배우자 는 패키지 도착 에만 패키지를 가져 오라는 지시를 “실행”합니다 . 훨씬 낫다!

이런 종류의 사고는 일상 생활에서 명백하지만 컴퓨터는 같은 종류의 상식을 가지고 있지 않습니다. 프로그래머가 일반적으로 파일에 쓰는 방법을 고려하십시오.

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 를 확인하십시오 .


답변

일반 영어로 콜백을 설명하는 방법은 무엇입니까?

일반 영어에서 콜백 기능은 작업 완료시 관리자 에게 ” 콜백 ” 하는 작업자 와 같습니다 .

호출 함수의 컨텍스트를 사용하여 한 함수를 다른 함수에서 호출하는 것과 어떻게 다릅니 까?

다른 함수에서 함수를 호출하는 것이 사실이지만 핵심은 콜백이 객체처럼 취급되므로 시스템 상태 (전략 디자인 패턴 등)에 따라 호출 할 함수를 변경할 수 있습니다.

초보자 프로그래머에게 그들의 힘을 어떻게 설명 할 수 있습니까?

콜백의 힘은 서버에서 데이터를 가져와야하는 AJAX 스타일 웹 사이트에서 쉽게 볼 수 있습니다. 새 데이터를 다운로드하는 데 시간이 걸릴 수 있습니다. 콜백이 없으면 새 데이터를 다운로드하는 동안 전체 사용자 인터페이스가 “정지”되거나 전체 페이지의 일부가 아닌 전체 페이지를 새로 고쳐야합니다. 콜백을 사용하면 “지금로드 중”이미지를 삽입하고 새 데이터가로드되면이를 대체 할 수 있습니다.

콜백이없는 일부 코드 :

function grabAndFreeze() {
    showNowLoading(true);
    var jsondata = getData('http://yourserver.com/data/messages.json');
    /* User Interface 'freezes' while getting data */
    processData(jsondata);
    showNowLoading(false);
    do_other_stuff(); // not called until data fully downloaded
}

function processData(jsondata) { // do something with the data
   var count = jsondata.results ? jsondata.results.length : 0;
   $('#counter_messages').text(['Fetched', count, 'new items'].join(' '));
   $('#results_messages').html(jsondata.results || '(no new messages)');
}

콜백으로 :

다음은 jQuery의 getJSON을 사용하는 콜백 예제입니다 .

function processDataCB(jsondata) { // callback: update UI with results
   showNowLoading(false);
   var count = jsondata.results ? jsondata.results.length : 0;
   $('#counter_messages').text(['Fetched', count, 'new items'].join(' '));
   $('#results_messages').html(jsondata.results || '(no new messages)');
}

function grabAndGo() { // and don't freeze
    showNowLoading(true);
    $('#results_messages').html(now_loading_image);
    $.getJSON("http://yourserver.com/data/messages.json", processDataCB);
    /* Call processDataCB when data is downloaded, no frozen User Interface! */
    do_other_stuff(); // called immediately
}

폐쇄와 함께 :

종종 콜백 은 작업을 완료하기 전에 Manager 로부터 정보를 얻어야 하는 작업자같은를state 사용하여 호출 기능에서 액세스해야합니다 . 를 만들려면 함수를 인라인하여 호출 컨텍스트에서 데이터를 볼 수 있습니다.closureclosure

/* Grab messages, chat users, etc by changing dtable. Run callback cb when done.*/
function grab(dtable, cb) {
    if (null == dtable) { dtable = "messages"; }
    var uiElem = "_" + dtable;
    showNowLoading(true, dtable);
    $('#results' + uiElem).html(now_loading_image);
    $.getJSON("http://yourserver.com/user/"+dtable+".json", cb || function (jsondata) {
       // Using a closure: can "see" dtable argument and uiElem variables above.
       var count = jsondata.results ? jsondata.results.length : 0,
           counterMsg = ['Fetched', count, 'new', dtable].join(' '),
           // no new chatters/messages/etc
           defaultResultsMsg = ['(no new ', dtable, ')'].join('');
       showNowLoading(false, dtable);
       $('#counter' + uiElem).text(counterMsg);
       $('#results'+ uiElem).html(jsondata.results || defaultResultsMsg);
    });
    /* User Interface calls cb when data is downloaded */

    do_other_stuff(); // called immediately
}

용법:

// update results_chatters when chatters.json data is downloaded:
grab("chatters");
// update results_messages when messages.json data is downloaded
grab("messages");
// call myCallback(jsondata) when "history.json" data is loaded:
grab("history", myCallback);

폐쇄

마지막으로, Douglas Crockford 의 정의는 다음 closure과 같습니다.

다른 기능 내에서 기능을 정의 할 수 있습니다. 내부 함수는 외부 함수의 변수 및 변수에 액세스 할 수 있습니다. 내부 함수에 대한 참조가 유지되면 (예 : 콜백 함수) 외부 함수의 변수도 유지됩니다.

또한보십시오:


답변

나는 많은 지능적인 사람들이 “콜백”이라는 단어가 두 가지의 일관성없는 방식으로 사용되었다는 현실을 강조하지 못하는 것을보고 기뻐했습니다.

두 가지 방법 모두 기존 기능에 추가 기능 (기능 정의, 익명 또는 명명 된)을 전달하여 기능을 사용자 정의하는 것과 관련됩니다. 즉.

customizableFunc(customFunctionality)

사용자 정의 기능이 단순히 코드 블록에 연결되어 있으면 기능을 사용자 정의한 것입니다.

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

이러한 종류의 주입 된 기능을 종종 “콜백”이라고 부르지 만 이에 대한 우발적 인 것은 없습니다. 가장 명백한 예는 배열을 수정하기 위해 배열의 각 요소에 적용 할 인수로 사용자 정의 함수를 제공하는 forEach 메소드입니다.

그러나 이것은 근본적 으로 AJAX 또는 node.js에서와 같이 또는 단순히 사용자 클릭 (예 : 마우스 클릭)과 같은 사용자 상호 작용 이벤트에 기능을 할당하는 비동기 프로그래밍을 위한 “콜백”기능의 사용과는 다릅니다 . 이 경우 전체 기능은 사용자 정의 기능을 실행하기 전에 우발적 인 이벤트가 발생할 때까지 기다리는 것입니다. 이는 사용자 상호 작용의 경우 분명하지만 디스크에서 파일을 읽는 것과 같이 시간이 걸릴 수있는 입출력 (입력 / 출력) 프로세스에서도 중요합니다. 이것은 “콜백”이라는 용어가 가장 분명한 의미입니다. i / o 프로세스가 시작되면 (예 : 디스크 또는 서버에서 파일을 읽어서 http 요청에서 데이터를 리턴하도록 요청하는 경우) 비동기프로그램이 끝날 때까지 기다리지 않습니다. 다음에 예약 된 모든 작업을 진행할 수 있으며 읽기 파일 또는 http 요청이 완료되었거나 실패했음을 알리고 사용자 지정 기능에서 데이터를 사용할 수 있다는 알림을받은 후에 만 ​​사용자 지정 기능으로 응답 할 수 있습니다. 전화로 업체에 전화를 걸고 “콜백”번호를 남기는 것과 같이 누군가가 다시 연락 할 수있을 때 전화를 걸 수 있습니다. 다른 업무에 얼마나 오랫동안 참석할 수 없는지 아는 사람에게는 전화를 끊는 것보다 낫습니다.

비동기식 사용에는 본질적으로 원하는 이벤트를 수신하는 일부 수단 (예 : i / o 프로세스 완료)이 포함되므로 이벤트 발생시 (및 발생하는 경우에만) 사용자 정의 “콜백”기능이 실행됩니다. 명백한 AJAX 예제에서, 데이터가 실제로 서버에서 도착하면 “콜백”함수가 트리거되어 해당 데이터를 사용하여 DOM을 수정하여 브라우저 창을 다시 그립니다.

요약하자면. 일부 사람들은 “콜백”이라는 단어를 사용하여 기존 함수에 인수로 삽입 할 수있는 모든 종류의 사용자 정의 기능을 나타냅니다. 그러나 적어도 나에게, 단어의 가장 적절한 사용은 주입 된 “콜백”기능이 비동기식으로 사용되는 곳입니다-통지 대기중인 이벤트가 발생할 때만 실행됩니다.


답변

프로그래머가 아닌 용어로 콜백은 프로그램의 빈칸입니다.

많은 종이 양식에서 흔히 볼 수있는 항목은 “비상시 전화 할 것”입니다. 빈 줄이 있습니다. 다른 사람의 이름과 전화 번호를 쓰십시오. 응급 상황이 발생하면 그 사람이 전화를받습니다.

  • 모두 같은 빈 양식을 얻지 만
  • 누구나 다른 비상 연락 번호를 쓸 수 있습니다.

이것이 핵심입니다. 양식 (일반적으로 다른 사람의 코드)을 변경하지 마십시오. 그러나 당신은 정보 (조각 누락 채울 수 귀하의 수).

예 1 :

콜백은 프로그램 동작을 추가하거나 변경하기 위해 사용자 정의 된 방법으로 사용됩니다. 예를 들어, 기능을 수행하지만 출력 인쇄 방법을 모르는 일부 C 코드를 사용하십시오. 문자열을 만들면됩니다. 문자열로 무엇을해야 하는지를 알아 내려고하면 빈 줄이 나타납니다. 그러나 프로그래머는 콜백을 쓸 수있는 빈칸을 주었다!

이 예에서는 연필을 사용하여 한 장의 용지에 공백을 채우지 않고 기능을 사용합니다 set_print_callback(the_callback).

  • 모듈 / 코드의 빈 변수는 빈 줄입니다.
  • set_print_callback 연필이야
  • 그리고 the_callback당신이 채우고있는 당신의 정보입니다.

이제 프로그램에서이 빈 줄을 채웠습니다. 출력을 인쇄해야 할 때마다 해당 빈 줄을보고 지시를 따릅니다 (예 : 거기에 놓은 함수 호출). 실제로는 화면, 로그 파일, 프린터, 네트워크 연결 또는 이들의 조합을 통해 당신이하고 싶은 일로 빈칸을 채웠습니다.

예 2 :

긴급 번호로 전화해야한다는 메시지가 나오면 종이 양식에 적힌 내용을 읽은 다음 읽은 번호로 전화하십시오. 해당 줄이 비어 있으면 아무 것도 수행되지 않습니다.

Gui 프로그래밍은 거의 같은 방식으로 작동합니다. 버튼을 클릭하면 프로그램은 다음에 수행 할 작업을 파악해야합니다. 콜백을 찾습니다. 이 콜백은 “Button1을 클릭 할 때 수행하는 작업”이라는 빈 칸에 나타납니다.

대부분의 IDE는 (예를 들어 button1_clicked) 요청할 때 빈 칸을 자동으로 채 웁니다 (기본 방법 작성 ). 그러나 그 빈칸은 어떤 방법을 사용 하셔도 좋습니다 . 당신은 메서드를 호출 할 수 run_computations또는 butter_the_biscuits당신이 적절한 빈에 그 콜백의 이름을 올려 놓을만큼을. 긴급 번호에는 “555-555-1212″를 입력하십시오. 그다지 의미가 없지만 허용됩니다.


마지막 참고 사항 : 콜백으로 채우는 빈 줄은 무엇입니까? 마음대로 삭제하고 다시 쓸 수 있습니다. (당신이 다른 질문을 해야하는지 아닌지 여부는 그것이 그들의 힘의 일부입니다)


답변

항상 예제로 시작하는 것이 좋습니다 :).

두 개의 모듈 A와 B가 있다고 가정 해 봅시다.

모듈 B에서 일부 이벤트 / 조건이 발생할 때 모듈 A에 알림 을 보내려고합니다 . 그러나 모듈 B는 모듈 A에 대해 전혀 알지 못합니다. 모듈 A는 함수 포인터를 통해 모듈 A의 특정 기능에 대한 주소 만 알고 있습니다. 모듈 A에 의해 제공됩니다.

따라서 모든 B는 이제 함수 포인터를 사용하여 특정 이벤트 / 조건이 발생할 때 모듈 A로 “콜백”됩니다. 콜백 함수 내부에서 추가 처리를 수행 할 수 있습니다.

*) 여기서 분명한 이점은 모듈 B에서 모듈 A에 대한 모든 정보를 추출한다는 것입니다. 모듈 B는 모듈 A가 누구인지 / 어떤 신경 쓰지 않아도됩니다.


답변

함수를 쓰려면 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);
}

그런 다음 compute (doA) 및 compute (doB)를 호출하면됩니다.

코드를 단순화하는 것 외에도 비동기 코드를 사용하면 전화로 누군가에게 전화를 걸어 콜백 번호를 남길 때와 마찬가지로 완료시 임의의 함수를 호출하여 완료되었음을 알 수 있습니다.