일반 영어로 콜백을 설명하는 방법은 무엇입니까? 호출 함수의 컨텍스트를 사용하여 한 함수를 다른 함수에서 호출하는 것과 어떻게 다릅니 까? 초보자 프로그래머에게 그들의 힘을 어떻게 설명 할 수 있습니까?
일반 영어로 콜백을 설명하는 방법은 무엇입니까? 호출 함수의 컨텍스트를 사용하여 한 함수를 다른 함수에서 호출하는 것과 어떻게 다릅니 까? 초보자 프로그래머에게 그들의 힘을 어떻게 설명 할 수 있습니까?
답변:
종종 응용 프로그램은 컨텍스트 / 상태에 따라 다른 기능을 실행해야합니다. 이를 위해 호출 할 함수에 대한 정보를 저장할 변수를 사용합니다. 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]
function(arg)
에서) processArray(arr,callback)
기능
나는이 죽은 것을 단순하게 유지하려고 노력할 것입니다. "콜백"은 첫 번째 함수를 매개 변수로 사용하는 다른 함수에 의해 호출되는 함수입니다. 많은 경우 "콜백"은 무언가 가 발생할 때 호출되는 함수입니다 . 그 무언가는 프로그래머 발언에서 "이벤트"를 호출 할 수 있습니다.
이 시나리오를 상상해보십시오. 며칠 안에 패키지를 예상하고 있습니다. 패키지는 이웃을위한 선물입니다. 따라서 일단 패키지를 받으면 이웃에게 가져 오기를 원합니다. 당신은 도시를 벗어 났으므로 배우자에게 지시 사항을 남깁니다.
패키지를 가져와 이웃에게 가져 오라고 할 수 있습니다. 배우자가 컴퓨터만큼 어리석은 경우, 문 앞에 앉아 패키지가 올 때까지 기다렸다가 (아무것도하지 말고) 한 번 들어 오면 이웃에게 가져다 줄 것입니다. 그러나 더 좋은 방법이 있습니다. 배우자에게 패키지를받은 후 이웃에게 가져 가야한다고 말하십시오. 그런 다음 패키지를받을 때까지 정상적으로 생활 할 수 있습니다.
이 예에서 패키지 수신은 "이벤트"이고 이웃에게 가져 오는 것은 "콜백"입니다. 배우자 는 패키지 도착 시 에만 패키지를 가져 오라는 지시를 "실행"합니다 . 훨씬 낫다!
이런 종류의 사고는 일상 생활에서 명백하지만 컴퓨터는 같은 종류의 상식을 가지고 있지 않습니다. 프로그래머가 일반적으로 파일에 쓰는 방법을 고려하십시오.
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 를 확인하십시오 .
open
작동 방식 에 대한 가정을하는 것 같습니다 . open
콜백이 실행되는 OS가 블랙 매직을하기를 기다리는 동안 내부적으로 차단 할 수있는 것은 그럴듯합니다 . 이 경우 결과에는 차이가 없습니다.
일반 영어로 콜백을 설명하는 방법은 무엇입니까?
일반 영어에서 콜백 기능은 작업 완료시 관리자 에게 " 콜백 " 하는 작업자 와 같습니다 .
호출 함수의 컨텍스트를 사용하여 한 함수를 다른 함수에서 호출하는 것과 어떻게 다릅니 까?
다른 함수에서 함수를 호출하는 것이 사실이지만 핵심은 콜백이 객체처럼 취급되므로 시스템 상태 (전략 디자인 패턴 등)에 따라 호출 할 함수를 변경할 수 있습니다.
초보자 프로그래머에게 그들의 힘을 어떻게 설명 할 수 있습니까?
콜백의 힘은 서버에서 데이터를 가져와야하는 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
사용하여 호출 기능에서 액세스해야합니다 . 를 만들려면 함수를 인라인하여 호출 컨텍스트에서 데이터를 볼 수 있습니다.closure
closure
/* 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을 수정하여 브라우저 창을 다시 그립니다.
요약하자면. 일부 사람들은 "콜백"이라는 단어를 사용하여 기존 함수에 인수로 삽입 할 수있는 모든 종류의 사용자 정의 기능을 나타냅니다. 그러나 적어도 나에게, 단어의 가장 적절한 사용은 주입 된 "콜백"기능이 비동기식으로 사용되는 곳입니다-통지 대기중인 이벤트가 발생할 때만 실행됩니다.
Array.prototype.forEach()
전달 된 함수와 arg로 전달 된 함수 setTimeout()
의 차이점과 프로그램에 대해 추론하는 방식에 따라 다른 색상의 말입니다. .
프로그래머가 아닌 용어로 콜백은 프로그램의 빈칸입니다.
많은 종이 양식에서 흔히 볼 수있는 항목은 "비상시 전화 할 것"입니다. 빈 줄이 있습니다. 다른 사람의 이름과 전화 번호를 쓰십시오. 응급 상황이 발생하면 그 사람이 전화를받습니다.
이것이 핵심입니다. 양식 (일반적으로 다른 사람의 코드)을 변경하지 마십시오. 그러나 당신은 정보 (조각 누락 채울 수 귀하의 수).
예 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)를 호출하면됩니다.
코드를 단순화하는 것 외에도 비동기 코드를 사용하면 전화로 누군가에게 전화를 걸어 콜백 번호를 남길 때와 마찬가지로 완료시 임의의 함수를 호출하여 완료되었음을 알 수 있습니다.
Johny 프로그래머는 스테이플러가 필요하므로 사무실 공급 부서로 가서 요청 양식을 작성한 후 요청 양식을 작성한 후 직원이 스테이플러의 창고 주변을 볼 때까지 기다릴 수 있습니다 (차단 기능 호출과 같이) ) 또는 다른 한편으로 이동하십시오.
이 작업에는 보통 시간이 걸리기 때문에 스테이플러가 픽업 준비가되었을 때 전화를 요청하는 요청 양식과 함께 메모를 작성하므로, 책상에서 낮잠과 같은 다른 작업을 수행 할 수 있습니다.
설명해야 할 두 가지 사항이 있습니다. 하나는 콜백의 작동 방식 (컨텍스트에 대한 지식없이 호출 할 수있는 함수를 전달하는 방법)과 다른 하나는 이벤트를 비동기 적으로 처리하는 데 사용되는 것입니다.
다른 답변에서 사용한 소포가 도착하기를 기다리는 비유는 두 가지를 모두 설명하는 좋은 방법입니다. 컴퓨터 프로그램에서는 컴퓨터가 소포를 기대하도록 지시합니다. 보통, 이제는 그곳에 앉아서 소포가 도착할 때까지 기다릴 것입니다 (아무 것도하지 않을 경우). 인간에게는 이것이 어리석게 들리지만 추가 조치가 없으면 컴퓨터에 전혀 자연스럽지 않습니다.
콜백은 현관 문의 종입니다. 집의 어디에 있는지 또는 종이 어떻게 작동하는지 알 필요없이 소포의 도착을 알리는 방법을 소포 서비스에 제공합니다. (예를 들어, 일부 "벨"은 실제로 전화를 발송합니다.) 상황에 상관없이 언제든지 "호출"할 수있는 "콜백 기능"을 제공 했으므로 이제는 현관에 앉아있는 것을 중단하고 " 때마다 이벤트 "(소포 도착).
친구가 당신의 집을 떠나고 있다고 가정하고, 당신이 그녀에게 "집에 도착하면 전화해서 내가 안전하게 도착했다는 것을 알려주세요"라고 말하십시오. 그것은 (문자 그대로) 콜백 입니다. 이것이 언어에 관계없이 콜백 함수입니다. 일부 작업이 완료되면 일부 프로 시저가 제어를 다시 전달하기를 원하므로 다시 호출하는 데 사용할 기능을 제공합니다.
예를 들어 파이썬에서
grabDBValue( (lambda x: passValueToGUIWindow(x) ))
grabDBValue
데이터베이스에서 값을 가져 와서 실제로 값으로 수행 할 작업을 지정하여 함수를 허용하도록 작성할 수 있습니다. 언제 또는 언제 grabDBValue
돌아올 지 모르지만, 언제 / 어떻게 할 것인지는 알고 있습니다. 여기에서는 GUI 창에 값을 보내는 익명 함수 (또는 lambda )를 전달합니다. 이렇게하면 프로그램의 동작을 쉽게 변경할 수 있습니다.
grabDBValue( (lambda x: passToLogger(x) ))
콜백 은 일반적인 정수, 문자열, 부울 등과 같이 함수가 첫 번째 클래스 값인 언어에서 잘 작동합니다 . C에서는 포인터를 전달하여 함수를 "통과"하고 호출자가 사용할 수 있습니다. Java에서 호출자는 클래스 외부에 함수 ( "실제로")가 없기 때문에 특정 메소드 이름을 가진 특정 유형의 정적 클래스를 요청합니다. 대부분의 다른 동적 언어에서는 간단한 구문으로 함수를 전달할 수 있습니다.
어휘 범위 (예 : Scheme 또는 Perl)가있는 언어에서는 다음과 같은 트릭을 사용할 수 있습니다.
my $var = 2;
my $val = someCallerBackFunction(sub callback { return $var * 3; });
# Perlistas note: I know the sub doesn't need a name, this is for illustration
$val
이 경우 6
콜백 은 정의 된 어휘 환경에서 선언 된 변수에 액세스 할 수 있기 때문 입니다. 어휘 범위와 익명의 콜백은 초보자 프로그래머를위한 추가 연구가 필요한 강력한 조합입니다.
실행할 코드가 있습니다. 일반적으로 호출 할 때 계속하기 전에 완료 될 때까지 기다립니다 (응용 프로그램이 회색으로 바뀌거나 커서의 회전 시간을 생성 할 수 있음).
다른 방법은이 코드를 병렬로 실행하고 자신의 작업을 수행하는 것입니다. 그러나 원래 코드가 호출 한 코드의 응답에 따라 다른 작업을 수행해야하는 경우 어떻게해야합니까? 그렇다면이 경우 호출 할 코드의 이름 / 위치를 전달할 수 있습니다. 이것은 "콜백"입니다.
일반 코드 : 정보-> 프로세스 정보-> 처리 결과-> 다른 작업을 계속하십시오.
콜백 사용 : 정보-> 프로세스 정보-> 다른 작업을 계속하십시오. 그리고 나중에 포인트-> 처리 결과 처리.
스레딩 및 기타와 같은 다른 특수 프로그래밍 리소스를 콜백하지 않으면 프로그램은 정확히 순차적으로 실행되는 일련의 명령이며 특정 조건에 따라 결정되는 일종의 "동적 동작"과 모든 가능한 시나리오 미리 프로그램해야합니다 .
따라서 프로그램에 실제 동적 동작을 제공해야하는 경우 콜백을 사용할 수 있습니다. 콜백을 사용하면 매개 변수, 이전에 정의 된 일부 매개 변수를 제공하는 다른 프로그램을 호출하는 프로그램으로 지시 할 수 있으며 일부 결과 ( 계약 또는 작업 서명 )를 기대할 수 있으므로 이러한 결과는 타사 프로그램에서 생성 / 처리 할 수 있습니다 이전에 알려지지 않았습니다.
이 기술은 프로그램, 기능, 객체 및 컴퓨터가 실행하는 모든 코드 단위에 적용되는 다형성의 기초입니다.
콜백의 예로 사용 된 인간 세계는 당신이 어떤 일을 할 때 잘 설명되어 있고, 당신이 화가라고 가정하고 ( 여기서는 당신이 주요 프로그램이며, 그림을 그리는 것입니다 ) 고객에게 전화하여 때로는 직업의 결과를 승인하도록 요청합니다 따라서 사진이 좋은지 결정합니다 ( 클라이언트는 타사 프로그램입니다 ).
위의 예에서 당신은 화가이며 결과를 승인하는 작업을 다른 사람들에게 "위임"하고, 그림은 매개 변수이며, 각각의 새로운 클라이언트 (콜백 "함수")는 자신이 원하는 것을 결정하는 작업 결과를 변경합니다. 그림에 대해 ( 클라이언트가 내린 결정은 "콜백 함수"에서 반환 된 결과입니다 ).
이 설명이 도움이 되길 바랍니다.
나에게 잠재적으로 장기 실행 작업을 제공했다고 가정 해 봅시다. 처음 만나는 5 명의 독특한 사람들의 이름을 얻으십시오. 인구 밀도가 낮은 지역에있는 경우 며칠이 걸릴 수 있습니다. 당신은 내가 뛰어 다니는 동안 당신의 손에 앉아있는 것에 정말로 관심이 없습니다. 그래서 당신이 말하기를, "당신이 목록을 얻었을 때, 저의 셀에 저를 불러서 다시 읽어주세요. 여기에 숫자가 있습니다."
추가 처리를 수행하기 위해 실행 해야하는 콜백 참조를 제공했습니다.
JavaScript에서는 다음과 같이 보일 수 있습니다.
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);
이것은 아마도 많은 방법으로 개선 될 수 있습니다. 예를 들어, 두 번째 콜백을 제공 할 수 있습니다. 1 시간 이상 걸리면 빨간 전화에 전화를 걸어 시간 초과 사실을 답변 한 사람에게 알립니다.
콜백은 두 번째 함수에 의해 호출되는 함수입니다. 이 두 번째 함수는 어떤 함수를 호출할지 미리 알지 못합니다. 따라서 콜백 함수 의 ID 는 어딘가에 저장되거나 두 번째 함수에 매개 변수로 전달됩니다. 프로그래밍 언어에 따라이 "정체성"은 콜백의 주소 또는 다른 종류의 포인터이거나 함수의 이름 일 수 있습니다. 교장은 동일하며, 기능을 명확하게 식별하는 정보를 저장하거나 전달합니다.
시간이되면 두 번째 함수는 콜백을 호출하여 해당 시점의 상황에 따라 매개 변수를 제공 할 수 있습니다. 가능한 콜백 세트에서 콜백을 선택할 수도 있습니다. 프로그래밍 언어는 두 번째 함수가 "ID"를 알고 콜백을 호출 할 수 있도록 일종의 구문을 제공해야합니다.
이 메커니즘은 가능한 많은 용도로 사용됩니다. 콜백을 사용하면 함수 디자이너가 제공 한 콜백을 호출하여 함수를 사용자 정의 할 수 있습니다. 예를 들어 정렬 함수는 콜백을 매개 변수로 사용하고이 콜백은 두 요소를 비교하여 어느 요소가 먼저 나오는지를 결정하는 함수일 수 있습니다.
그런데, 프로그래밍 언어에 따라, 상기 논의에서 "기능"이라는 단어는 "블록", "클로저", "람다"등으로 대체 될 수있다.
보통 우리는 변수를 함수로 보냈습니다. 인수로 제공되기 전에 변수를 처리해야하는 작업이 있다고 가정합니다. 콜백을 사용할 수 있습니다.
function1(var1, var2)
일반적인 방법입니다.
var2
처리 후 인수로 보내 려면 어떻게해야 합니까?
function1(var1, function2(var2))
이것은 콜백의 한 유형입니다. 여기서 function2
코드를 실행하고 변수를 초기 함수로 되돌립니다.
콜백을 가르치려면 먼저 포인터를 가르쳐야합니다. 학생들이 변수에 대한 포인터 개념을 이해하면 콜백 아이디어가 더 쉬워집니다. C / C ++를 사용한다고 가정하면 다음 단계를 수행 할 수 있습니다.
더 많은 것들이있을 수 있습니다. 학생들을 참여 시키면 알게 될 것입니다. 도움이 되었기를 바랍니다.
일반 영어로는 콜백이 약속입니다. Joe, Jane, David 및 Samantha는 카풀을 공유하여 작업합니다. 조는 오늘 운전하고 있습니다. Jane, David 및 Samantha는 몇 가지 옵션이 있습니다.
옵션 1 : 이것은 Joe가 외부에 있는지 Jane이 "루프"검사에 빠지는 폴링 예제와 비슷합니다. 제인은 그동안 다른 일을 할 수 없습니다.
옵션 2 : 이것이 콜백 예입니다. Jane은 Joe에게 밖에있을 때 초인종을 울리라고 말합니다. 그녀는 그에게 도어 벨을 울리는 "기능"을 제공합니다. Joe는 초인종이 어떻게 작동하는지 또는 그것이 어디에 있는지 알 필요가 없으며, 그 기능을 호출해야합니다.
콜백은 "이벤트"에 의해 구동됩니다. 이 예에서 "이벤트"는 Joe의 도착입니다. 예를 들어 Ajax에서 이벤트는 비동기 요청의 "성공"또는 "실패"일 수 있으며 각 이벤트는 동일하거나 다른 콜백을 가질 수 있습니다.
JavaScript 애플리케이션 및 콜백 측면에서. 또한 "클로저"와 응용 프로그램 컨텍스트를 이해해야합니다. "this"는 자바 스크립트 개발자를 쉽게 혼동 할 수 있습니다. 이 예에서 각 개인의 "ring_the_door_bell ()"메서드 / 콜백 내에는 각 사람이 아침 루틴 ex를 기준으로해야하는 다른 방법이있을 수 있습니다. "turn_off_the_tv ()". "this"가 "Jane"개체 또는 "David"개체를 참조하여 Joe가 선택하기 전에 필요한 다른 작업을 수행 할 수 있도록합니다. 여기서 Joe와의 콜백을 설정하려면 "this"가 올바른 객체를 가리 키도록 메소드를 패러디해야합니다.
희망이 도움이됩니다!
콜백 함수 란 무엇입니까?
이 첫 번째 질문에 대한 간단한 대답은 콜백 함수가 함수 포인터를 통해 호출되는 함수라는 것입니다. 함수의 포인터 (주소)를 다른 인수에 대한 인수로 전달하면 해당 포인터를 사용하여 함수를 호출 할 때 해당 함수가 가리키는 것이 콜백이라고합니다.
콜백 함수는 추적하기 어렵지만 때로는 매우 유용합니다. 특히 라이브러리를 디자인 할 때. 콜백 함수는 사용자에게 함수 이름을 요청하는 것과 같으며 특정 조건에서 해당 함수를 호출합니다.
예를 들어 콜백 타이머를 작성합니다. 기간과 호출 할 함수를 지정할 수 있으며 그에 따라 함수가 콜백됩니다. “5 초 동안 10 초마다 myfunction ()을 실행하십시오”
또는 함수 이름 목록을 전달하여 함수 디렉토리를 작성하고 라이브러리에 따라 콜백하도록 요청할 수 있습니다. "성공이면 콜백 success (), 실패하면 콜백 fail ()."
간단한 함수 포인터 예제를 보자
void cbfunc()
{
printf("called");
}
int main ()
{
/* function pointer */
void (*callback)(void);
/* point to your callback function */
callback=(void *)cbfunc;
/* perform callback */
callback();
return 0;
}
콜백 함수에 인수를 전달하는 방법?
콜백을 구현하기위한 함수 포인터는 void *를 사용하여 구조를 포함한 모든 유형의 변수를 사용할 수 있음을 관찰했습니다. 따라서 구조별로 여러 인수를 전달할 수 있습니다.
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;
}
콜백은 조건이 충족 될 때 실행되도록 예약 된 방법입니다.
"실제 세계"의 예는 로컬 비디오 게임 상점입니다. Half-Life 3을 기다리고 있습니다. 매일 매장에 있는지 확인하지 말고 목록에 이메일을 등록하여 게임이 가능할 때 알림을 받으십시오. 이메일은 "콜백"이되고 충족되는 조건은 게임의 가용성입니다.
"프로그래머"예제는 버튼을 클릭 할 때 작업을 수행하려는 웹 페이지입니다. 버튼의 콜백 메소드를 등록하고 다른 작업을 계속합니다. 사용자가 버튼을 클릭하면 브라우저는 해당 이벤트에 대한 콜백 목록을보고 메소드를 호출합니다.
콜백은 이벤트를 비동기 적으로 처리하는 방법입니다. 콜백이 언제 실행 될지 또는 전혀 실행 될지 알 수 없습니다. 장점은 응답을 기다리는 동안 프로그램 및 CPU주기가 다른 작업을 수행 할 수 있도록하는 것입니다.
단순하고 단순함 : 콜백은 다른 함수에 부여하여 호출 할 수있는 함수입니다 .
일반적으로 일부 작업이 완료되면 호출됩니다. 콜백을 다른 함수에 제공하기 전에 콜백을 작성하므로 콜 사이트의 컨텍스트 정보로 콜백을 초기화 할 수 있습니다. 이것이 이름이 call * back * 인 이유입니다. 첫 번째 함수는 호출 된 위치에서 컨텍스트로 다시 호출됩니다.
“컴퓨터 프로그래밍에서 콜백은 실행 코드 또는 실행 코드에 대한 참조로 다른 코드에 대한 인수로 전달됩니다. 이를 통해 하위 레벨 소프트웨어 계층이 상위 레벨 계층에 정의 된 서브 루틴 (또는 기능)을 호출 할 수 있습니다.” -위키 백과
함수 포인터를 사용하여 C에서 콜백
C에서는 콜백이 함수 포인터를 사용하여 구현됩니다. 함수 포인터-이름에서 알 수 있듯이 함수에 대한 포인터입니다.
예를 들어, int (* ptrFunc) ();
여기서 ptrFunc는 인수를 사용하지 않고 정수를 반환하는 함수에 대한 포인터입니다. 괄호 안에 넣는 것을 잊지 마십시오. 그렇지 않으면 컴파일러는 ptrFunc가 일반 함수 이름이라고 가정합니다.이 함수는 아무것도 취하지 않고 정수에 대한 포인터를 반환합니다.
다음은 함수 포인터를 보여주는 코드입니다.
#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;
}
이제 함수 포인터를 사용하여 C에서 콜백의 개념을 이해하려고합시다.
완전한 프로그램에는 callback.c, reg_callback.h 및 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)();
}
이 프로그램을 실행하면 출력은
이것은 메인 프로그램 내에서 my_callback 내부의 register_callback 내에서 함수 콜백을 보여주는 프로그램입니다.
상위 계층 함수는 일반 호출로 하위 계층 함수를 호출하고 콜백 메커니즘을 통해 하위 계층 함수는 콜백 함수에 대한 포인터를 통해 상위 계층 함수를 호출 할 수 있습니다.
인터페이스를 사용한 자바 콜백
Java에는 함수 포인터 개념이 없습니다. 인터페이스 메커니즘을 통해 콜백 메커니즘을 구현합니다. 여기에서 함수 포인터 대신에 수신자가 작업을 마칠 때 호출 될 메소드가있는 인터페이스를 선언합니다.
예제를 통해 보여 드리겠습니다.
콜백 인터페이스
public interface Callback
{
public void notify(Result result);
}
발신자 또는 상위 레벨 클래스
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
}
}
수신자 또는 하위 계층 기능
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
}
}
EventListener 패턴을 사용한 콜백
이 패턴은 특정 작업이 완료되었음을 0 ~ n 개의 관찰자 / 리스너에게 알리는 데 사용됩니다.
콜백 메커니즘과 EventListener / Observer 메커니즘의 차이점은 콜백에서는 수신자가 단일 발신자에게 알리는 반면 Eventlisener / Observer에서는 수신자가 해당 이벤트에 관심이있는 사람에게 통지 할 수 있다는 것입니다 (알림은 작업을 트리거하지 않은 응용 프로그램)
예를 통해 설명하겠습니다.
이벤트 인터페이스
public interface Events {
public void clickEvent();
public void longClickEvent();
}
수업 위젯
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);
}
}
수업 버튼
public class Button extends Widget{
private String mButtonText;
public Button (){
}
public String getButtonText() {
return mButtonText;
}
public void setButtonText(String buttonText) {
this.mButtonText = buttonText;
}
}
클래스 체크 박스
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;
}
}
활동 클래스
패키지 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();
}
}
다른 클래스
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...");
}
}
메인 클래스
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);
}
}
위의 코드에서 볼 수 있듯이 기본적으로 응용 프로그램에서 발생할 수있는 모든 이벤트를 나열하는 이벤트라는 인터페이스가 있습니다. Widget 클래스는 Button, Checkbox와 같은 모든 UI 구성 요소의 기본 클래스입니다. 이러한 UI 구성 요소는 실제로 프레임 워크 코드에서 이벤트를받는 객체입니다. 위젯 클래스는 Events 인터페이스를 구현하며 OnClickEventListener 및 OnLongClickEventListener라는 두 개의 중첩 된 인터페이스를 가지고 있습니다.
이 두 인터페이스는 Button 또는 Checkbox와 같은 위젯 파생 UI 구성 요소에서 발생할 수있는 이벤트를 수신합니다. 따라서이 예제를 Java 인터페이스를 사용하는 이전 콜백 예제와 비교하면이 두 인터페이스가 콜백 인터페이스로 작동합니다. 따라서 상위 레벨 코드 (여기 활동)는이 두 인터페이스를 구현합니다. 그리고 이벤트가 위젯에 발생할 때마다 상위 레벨 코드 (또는 상위 레벨 코드로 구현 된 이러한 인터페이스의 메소드 (여기서는 Activity))가 호출됩니다.
이제 콜백과 이벤트 리스너 패턴의 기본적인 차이점에 대해 설명하겠습니다. 콜백을 사용하면 수신자는 단일 발신자에게만 알릴 수 있습니다. 그러나 EventListener 패턴의 경우 응용 프로그램의 다른 부분이나 클래스는 단추 또는 확인란에서 발생할 수있는 이벤트를 등록 할 수 있습니다. 이러한 종류의 클래스의 예는 OtherClass입니다. OtherClass의 코드가 표시되면 Activity에 정의 된 Button에서 발생할 수있는 ClickEvent에 대한 리스너로 등록 된 것입니다. 흥미로운 부분은 액티비티 (발신자) 외에 버튼에서 클릭 이벤트가 발생할 때마다이 OtherClass에 통지된다는 것입니다.
콜백을 사용하면 다른 코드 블록에 자신의 코드를 삽입하여 다른 시간에 실행될 수 있으며, 필요에 따라 다른 코드 블록의 동작을 수정하거나 추가 할 수 있습니다. 보다 유지 보수가 쉬운 코드를 보유하면서 유연성과 사용자 정의성을 확보 할 수 있습니다.
하드 코드 감소 = 유지 관리 및 변경 용이성 = 시간 단축 = 비즈니스 가치 증대 = 위대함.
예를 들어, Underscore.js를 사용하는 자바 스크립트에서는 다음과 같이 배열에서 모든 짝수 요소를 찾을 수 있습니다.
var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> [2, 4, 6]
Underscore.js 제공 예 : http://documentcloud.github.com/underscore/#filter
동료에게 작업을 제공하는 방법을 생각하십시오. 간단한 작업은 다음과 같습니다.
Solve these equations:
x + 2 = y
2 * x = 3 * y
동료가 부지런히 수학을 수행하고 다음과 같은 결과를 제공합니다.
x = -6
y = -4
그러나 동료에게는 문제가 있습니다. 그는와 같은 표기법을 항상 이해 ^
하지는 못하지만 설명으로이를 이해합니다. 와 같은 exponent
. 그가 이들 중 하나를 발견 할 때마다 다음과 같은 결과가 나타납니다.
I don't understand "^"
이를 위해서는 캐릭터가 동료에게 의미하는 바를 설명한 후 전체 명령어 세트를 다시 작성해야하며 질문 사이에 항상 기억하는 것은 아닙니다. 그리고 그는 저에게 물어 보는 것과 같이 당신의 팁을 기억하는 데 어려움이 있습니다. 그러나 그는 항상 최선을 다해 서면 지시를 따릅니다.
해결책을 생각하면 모든 지침에 다음을 추가하기 만하면됩니다.
If you have any questions about symbols, call me at extension 1234 and I will tell you its name.
이제 문제가있을 때마다 잘못된 응답을 제공하고 프로세스를 다시 시작하지 않고 전화를 걸어 묻습니다.
웹 페이지 다운로드 측면에서 다음과 같습니다.
프로그램이 휴대 전화에서 실행되고 http://www.google.com 웹 페이지를 요청하고 있습니다. 프로그램을 동기식으로 작성하면 모든 데이터가 다운로드 될 때까지 데이터를 다운로드하기 위해 작성하는 기능이 계속 실행됩니다. 이는 UI가 새로 고침되지 않으며 기본적으로 정지 된 것으로 나타납니다. 콜백을 사용하여 프로그램을 작성하는 경우 데이터를 요청하고 "완료되면이 기능을 실행하십시오"라고 말합니다. 이를 통해 파일을 다운로드하는 동안 UI가 여전히 사용자 상호 작용을 허용 할 수 있습니다. 웹 페이지 다운로드가 완료되면 결과 함수 (콜백)가 호출되고 데이터를 처리 할 수 있습니다.
기본적으로 결과를 기다리는 동안 무언가를 요청하고 계속 실행할 수 있습니다. 콜백 함수를 통해 결과가 다시 나오면 중단 된 작업을 선택할 수 있습니다.