수색…


간단한 콜백 사용 예

콜백은 코드 를 변경하지 않고 함수 (또는 메서드)의 기능을 확장하는 방법을 제공합니다. 이 방법은 종종 모듈 (라이브러리 / 플러그인)에서 사용되며 코드는 변경되지 않아야합니다.

주어진 값 배열의 합을 계산하여 다음 함수를 작성했다고 가정 해보십시오.

function foo(array) {
    var sum = 0;
    for (var i = 0; i < array.length; i++) {
        sum += array[i];
    }
    return sum;
}

이제 우리는 배열의 각 값을 가지고 뭔가를하고 싶다고 가정합니다. 예를 들어 alert() 사용하여 표시합니다. foo 코드에서 다음과 같이 적절하게 변경할 수 있습니다.

function foo(array) {
    var sum = 0;
    for (var i = 0; i < array.length; i++) {
        alert(array[i]);
        sum += array[i];
    }
    return sum;
}

그러나 alert() 대신 console.log 를 사용하기로 결정했다면 어떻게 될까요? 분명히 foo 의 코드를 변경하면 각 값을 가지고 뭔가 다른 것을하기로 결정할 때마다 좋은 생각이 아닙니다. foo 의 코드를 변경하지 않고 우리의 마음을 바꾸는 옵션을 갖는 것이 훨씬 낫습니다. 이것이 바로 콜백의 유스 케이스 다. 우리는 단지 foo 의 서명과 본문을 약간 변경해야합니다.

function foo(array, callback) {
    var sum = 0;
    for (var i = 0; i < array.length; i++) {
        callback(array[i]);
        sum += array[i];
    }
    return sum;
}

이제 매개 변수를 변경하여 foo 의 동작을 변경할 수 있습니다.

var array = [];
foo(array, alert);
foo(array, function (x) {
    console.log(x);
});

비동기 함수를 사용한 예

jQuery에서 JSON 데이터를 가져 오는 $.getJSON() 메소드는 비동기식입니다. 따라서 코드를 콜백에 전달하면 JSON을 가져온 후에 코드가 호출됩니다.

$.getJSON() 구문 :

$.getJSON( url, dataObject, successCallback );

$.getJSON() 코드의 예 :

$.getJSON("foo.json", {}, function(data) {
    // data handling code
});

데이터가 실제로 수신하기 전에하기 때문에 데이터 처리 코드는 가능성이 호출 될 것이기 때문에 다음은 작동하지 않을 것입니다 $.getJSON 기능은 시간의 길이가 지정되지 않은 소요가 JSON을 대기로 호출 스택을 보유하지 않습니다.

$.getJSON("foo.json", {});
// data handling code

비동기 함수의 또 다른 예는 jQuery의 animate() 함수입니다. 애니메이션을 실행하는 데 지정된 시간이 걸리기 때문에 애니메이션 다음에 직접 코드를 실행하는 것이 바람직합니다.

.animate() 구문 :

jQueryElement.animate( properties, duration, callback );

예를 들어, 요소가 완전히 사라진 후 페이드 아웃 애니메이션을 만들려면 다음 코드를 실행하면됩니다. 콜백의 사용에 유의하십시오.

elem.animate( { opacity: 0 }, 5000, function() {
    elem.hide();
} );

이렇게하면 함수 실행이 끝난 직후에 요소를 숨길 수 있습니다. 이것은 다음과 다릅니다 :

elem.animate( { opacity: 0 }, 5000 );
elem.hide();

왜냐하면 후자는 animate() (비동기 함수)가 완료 될 때까지 기다리지 않기 때문에 요소가 즉시 숨겨져 바람직하지 않은 결과가 발생하기 때문입니다.

콜백이란 무엇입니까?

이것은 일반적인 함수 호출입니다.

console.log("Hello World!");

정상적인 기능을 호출하면 작업을 수행 한 다음 호출자에게 다시 제어권을 반환합니다.

그러나 때로는 함수가 호출자에게 제어를 반환하여 작업을 수행해야하는 경우가 있습니다.

[1,2,3].map(function double(x) {
    return 2 * x;
});

위의 예제에서 double 함수는 함수 map 대한 콜백입니다. 이유는 다음과 같습니다.

  1. 함수 double 은 호출자가 함수 map 에 지정합니다.
  2. 함수 map 은 작업을 수행하기 위해 double 0 번 이상 호출해야합니다.

따라서 함수 map 은 함수 double 호출 할 때마다 기본적으로 호출자에게 다시 제어권을 반환합니다. 따라서 "콜백"이름.


함수는 둘 이상의 콜백을 허용 할 수 있습니다.

promise.then(function onFulfilled(value) {
    console.log("Fulfilled with value " + value);
}, function onRejected(reason) {
    console.log("Rejected with reason " + reason);
});

여기서 다음 함수는 then 두 콜백 함수 수락 onFulfilledonRejected . 또한이 두 콜백 함수 중 하나만 실제로 호출됩니다.

무엇보다 흥미로운 점은 함수가 있다는 것입니다 then 콜백 중 하나가 호출되기 전에 반환합니다. 따라서 콜백 함수는 원래 함수가 반환 된 후에도 호출 될 수 있습니다.

연속 (동기 및 비동기)

콜백은 메소드가 완료된 후에 실행될 코드를 제공하는 데 사용할 수 있습니다.

/**
 * @arg {Function} then continuation callback
 */
function doSomething(then) {
  console.log('Doing something');
  then();
}

// Do something, then execute callback to log 'done'
doSomething(function () {
  console.log('Done');
});

console.log('Doing something else');

// Outputs:
//   "Doing something"
//   "Done"
//   "Doing something else"

위의 doSomething() 메서드는 doSomething() 반환 될 때까지 콜백 실행 블록과 동 기적으로 실행되어 인터프리터가 이동하기 전에 콜백이 실행되도록합니다.

콜백은 코드를 비동기 적으로 실행하는 데에도 사용할 수 있습니다.

doSomethingAsync(then) {
  setTimeout(then, 1000);
  console.log('Doing something asynchronously');
}

doSomethingAsync(function() {
  console.log('Done');
});

console.log('Doing something else');

// Outputs:
//   "Doing something asynchronously"
//   "Doing something else"
//   "Done"

그런 then 콜백은 doSomething() 메소드의 연속으로 간주됩니다. 함수의 마지막 명령어로 콜백을 제공하는 것은 꼬리 호출 이라고하며 ES2015 인터프리터에 의해 최적화됩니다 .

오류 처리 및 제어 흐름 분기

콜백은 종종 오류 처리를 제공하는 데 사용됩니다. 이것은 오류가 발생할 때만 일부 명령어가 실행되는 제어 흐름 분기의 한 형태입니다.

const expected = true;

function compare(actual, success, failure) {
  if (actual === expected) {
    success();
  } else {
    failure();
  }
}

function onSuccess() {
  console.log('Value was expected');
}

function onFailure() {
  console.log('Value was unexpected/exceptional');
}

compare(true, onSuccess, onFailure);
compare(false, onSuccess, onFailure);

// Outputs:
//   "Value was expected"
//   "Value was unexpected/exceptional"

위의 compare() 코드 실행은 예상되는 값과 실제 값이 같을 때의 success 과 다른 경우의 error 두 가지 분기를 가질 수 있습니다. 이는 비동기식 명령어 다음에 제어 흐름이 분기되어야 할 때 특히 유용합니다.

function compareAsync(actual, success, failure) {
  setTimeout(function () {
    compare(actual, success, failure)
  }, 1000);
}

compareAsync(true, onSuccess, onFailure);
compareAsync(false, onSuccess, onFailure);
console.log('Doing something else');

// Outputs:
//   "Doing something else"
//   "Value was expected"
//   "Value was unexpected/exceptional"

다중 콜백은 상호 배타적 일 필요는 없습니다. 두 메소드 모두 호출 될 수 있습니다. 비슷하게, compare() 는 옵션 인 콜백으로 작성 될 수 있습니다 (기본 값으로 noop 사용 - Null Object 패턴 참조).

콜백과`this`

종종 콜백을 사용할 때 특정 컨텍스트에 대한 액세스를 원할 때가 있습니다.

function SomeClass(msg, elem) {
  this.msg = msg;
  elem.addEventListener('click', function() {
    console.log(this.msg);  // <= will fail because "this" is undefined
  });
}

var s = new SomeClass("hello", someElement);

솔루션

  • bind 사용

    bind 효과적으로 설정하는 새로운 함수 생성 this 전달 된 무엇에 bind 다음 원래 함수를 호출합니다.

      function SomeClass(msg, elem) {
        this.msg = msg;
        elem.addEventListener('click', function() {
          console.log(this.msg);  
        }.bind(this));  // <=-  bind the function to `this`
      }
    
  • 화살표 기능 사용

    화살표 기능은 자동으로 현재를 바인딩 this 컨텍스트를.

      function SomeClass(msg, elem) {
        this.msg = msg;
        elem.addEventListener('click',() => {   // <=-  arrow function binds `this`
          console.log(this.msg);  
        });
      }
    

종종 멤버 함수를 호출하여 이벤트에 전달 된 인수를 함수에 전달하는 것이 좋습니다.

솔루션 :

  • 바인드 사용

      function SomeClass(msg, elem) {
        this.msg = msg;
        elem.addEventListener('click', this.handleClick.bind(this));
      }
    
      SomeClass.prototype.handleClick = function(event) {
        console.log(event.type, this.msg);
      };
    
  • 화살표 함수와 나머지 연산자 사용

      function SomeClass(msg, elem) {
        this.msg = msg;
        elem.addEventListener('click', (...a) => this.handleClick(...a));
      }
    
      SomeClass.prototype.handleClick = function(event) {
        console.log(event.type, this.msg);
      };
    
  • 특히 DOM 이벤트 리스너의 경우 EventListener 인터페이스를 구현할 수 있습니다.

      function SomeClass(msg, elem) {
        this.msg = msg;
        elem.addEventListener('click', this);
      }
    
      SomeClass.prototype.handleEvent = function(event) {
        var fn = this[event.type];
        if (fn) {
           fn.apply(this, arguments);
        }
      };
      
      SomeClass.prototype.click = function(event) {
        console.log(this.msg);
      };
    

화살표 기능을 사용한 콜백

화살표 함수를 콜백 함수로 사용하면 코드 줄을 줄일 수 있습니다.

arrow 함수의 기본 구문은 다음과 같습니다.

() => {}

이것은 콜백으로 사용할 수 있습니다.

예를 들어 배열 [1,2,3,4,5]의 모든 요소를 ​​인쇄하려면

화살표 기능이 없으면 코드는 다음과 같이 보입니다.

[1,2,3,4,5].forEach(function(x){
                 console.log(x);
            }

화살표 기능으로 축소 할 수 있습니다.

[1,2,3,4,5].forEach(x => console.log(x));

여기서 콜백 함수 function(x){console.log(x)}x=>console.log(x) 축소됩니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow