JavaScript에서 콜백 함수에 대한 이해


163

콜백으로 다른 함수에 함수를 전달하고 실행하는 것을 이해하지만 최선의 구현을 이해하지 못합니다. 나는 다음과 같은 매우 기본적인 예를 찾고 있습니다.

var myCallBackExample = {
    myFirstFunction : function( param1, param2, callback ) {
        // Do something with param1 and param2.
        if ( arguments.length == 3 ) {
            // Execute callback function.
            // What is the "best" way to do this?
        }
    },
    mySecondFunction : function() {
        myFirstFunction( false, true, function() {
            // When this anonymous function is called, execute it.
        });
    }
};

myFirstFunction에서 new callback ()을 반환하면 작동하고 익명 함수가 실행되지만 올바른 접근 방식은 아닙니다.


어떤 의미에서 맞습니까? 일반적으로 콜백은 이벤트 처리기 (대부분 비동기식 인 Ajax 호출)에 사용되며 기본적으로 응답이 언제 올지 알 수없는 것입니다.
cletus

2
그런데 arguments는 array와 같지만 array이 아닌 array이므로 argument.length를 수행 할 수 없지만 slice 메서드를 사용하여 배열로 변환 할 수 있습니다.
paul

1
@paul, arguments배열이 아닌 것이 맞지만 여전히 길이를 참조 할 수 있습니다 arguments.length-시도해보십시오. 이 특성은 실제로 전달 된 인수 수를 나타내며 함수 시그니처의 매개 변수 수는 아닙니다.
hotshot309

답변:


132

당신은 그냥 말할 수 있습니다

callback();

또는 콜백 내에서 call값을 조정하려는 경우 메소드 를 사용할 수 있습니다 this.

callback.call( newValueForThis);

함수 내부에는 this무엇이든지있을 것 newValueForThis입니다.


91

콜백이 존재하고 실행 가능한 함수인지 확인해야합니다.

if (callback && typeof(callback) === "function") {
    // execute the callback, passing parameters as necessary
    callback();
}

많은 라이브러리 (jQuery, dojo 등)는 비동기 함수와 비슷한 패턴을 사용하고 모든 비동기 함수 (nodejs는 일반적으로 전달 errordata콜백)에 node.js를 사용합니다 . 소스 코드를 살펴보면 도움이 될 것입니다!


callback문자열로 캐스팅 한 다음 유형을 확인합니까? 이것이 성능을 향상 시킵니까? 이것은 타입을 확인하고 변환 된 부울이 true를 반환하는지 확인한 다음 타입을 다시 확인하고 문자열을 테스트하는 것과 같습니다.
두통

콜백에 대한 첫 번째 어설 션이 필요한 이유가 궁금합니다 ... null 또는 undefined를 확인해야합니까? typeof(callback)당신을 위해 그것을 달성 하지 않겠습니까 ? typeof(null) === "Object",typeof("undefined") === "undefined"
PJH

1
단락 AND. 콜백이 존재하지 않으면 그 유형을 계산하지 않아도됩니다. 그래도 네 말이 맞아 typeof ()에는 필요하지 않지만 jsperf를 수행하고 단락이 가치가 있는지 확인합니다.
arunjitsingh

@headacheCoder- callback문자열로 캐스트되지 않고 호출되기 전에 해당 유형이 함수인지 확인합니다. 이 코드는 아마도 callback인수로 받아 들일 수 있으며 인수가 호출 가능한 유형인지 확실하지 않거나 코드가 다른 typeof인수 에 다르게 반응 할 수있는 다형성의 형태를 제공하려는 시도에서 다양한 유형이 될 수 있습니다 .
LeeGee

34

함수를 실행할 수있는 3 가지 주요 가능성이 있습니다.

var callback = function(x, y) {
    // "this" may be different depending how you call the function
    alert(this);
};
  1. 콜백 (argument_1, argument_2);
  2. callback.call (some_object, argument_1, argument_2);
  3. callback.apply (some_object, [argument_1, argument_2]);

선택하는 방법은 다음 여부에 따라 다릅니다.

  1. 인수는 Array에 저장되거나 고유 한 변수로 저장됩니다.
  2. 일부 객체의 컨텍스트에서 해당 함수를 호출하려고합니다. 이 경우 해당 콜백에서 "this"키워드를 사용하면 call () 또는 apply ()에서 인수로 전달 된 객체를 참조하게됩니다. 객체 컨텍스트를 전달하지 않으려면 null 또는 undefined를 사용하십시오. 후자의 경우 전역 객체는 "this"에 사용됩니다.

Function.call , Function.apply 문서


6

콜백은 신호에 관한 것이며 "신규"는 객체 인스턴스 생성에 관한 것입니다.

이 경우 "callback ();"만 실행하는 것이 더 적합합니다. "return new callback ()"보다 반환 값이없는 작업을 수행하지 않기 때문입니다.

(그리고 arguments.length == 3 테스트는 실제로 복잡하고 혼란스럽고 콜백 매개 변수가 존재하고 함수인지 확인하는 것이 좋습니다.)


6

적절한 구현은 다음과 같습니다.

if( callback ) callback();

콜백 매개 변수를 선택 사항으로 만듭니다.


콜백 인수가 함수가 아닌 경우 어떻게합니까?
Yaki Klein

2

당신이 사용할 수있는:

if (callback && typeof(callback) === "function") {
    callback();
}

아래 예제는 좀 더 포괄적입니다.

function mySandwich(param1, param2, callback) {
  alert('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2);
  var sandwich = {
      toppings: [param1, param2]
    },
    madeCorrectly = (typeof(param1) === "string" && typeof(param2) === "string") ? true : false;
  if (callback && typeof(callback) === "function") {
    callback.apply(sandwich, [madeCorrectly]);
  }
}

mySandwich('ham', 'cheese', function(correct) {
  if (correct) {
    alert("Finished eating my " + this.toppings[0] + " and " + this.toppings[1] + " sandwich.");
  } else {
    alert("Gross!  Why would I eat a " + this.toppings[0] + " and " + this.toppings[1] + " sandwich?");
  }
});


1

다음은 callback()JavaScript 에서 함수 를 설명하는 기본 예입니다 .

var x = 0;

function testCallBack(param1, param2, callback) {
  alert('param1= ' + param1 + ', param2= ' + param2 + ' X=' + x);
  if (callback && typeof(callback) === "function") {
    x += 1;
    alert("Calla Back x= " + x);
    x += 1;
    callback();
  }
}

testCallBack('ham', 'cheese', function() {
  alert("Function X= " + x);
});

JSFiddle


1

function checkCallback(cb) {
  if (cb || cb != '') {
    if (typeof window[cb] === 'undefined') alert('Callback function not found.');
    else window[cb].call(this, Arg1, Arg2);
  }
}

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.