수색…
간단한 콜백 사용 예
콜백은 코드 를 변경하지 않고 함수 (또는 메서드)의 기능을 확장하는 방법을 제공합니다. 이 방법은 종종 모듈 (라이브러리 / 플러그인)에서 사용되며 코드는 변경되지 않아야합니다.
주어진 값 배열의 합을 계산하여 다음 함수를 작성했다고 가정 해보십시오.
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
대한 콜백입니다. 이유는 다음과 같습니다.
- 함수
double
은 호출자가 함수map
에 지정합니다. - 함수
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
두 콜백 함수 수락 onFulfilled
및 onRejected
. 또한이 두 콜백 함수 중 하나만 실제로 호출됩니다.
무엇보다 흥미로운 점은 함수가 있다는 것입니다 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)
축소됩니다.