Параметри в callback
Параметри передаються в callback так само, як у будь-яку іншу функцію: достатньо викликати колбек з потрібними аргументами всередині приймальної функції. Ви віддаєте лише посилання на функцію, а конкретні значення підставляє той код, який цей колбек викликає.
Теорія
TL;DR
- Аргументи колбеку передає не викликач, а та функція, якій колбек віддали:
callback(data). - Імена параметрів у колбеку ваші власні, важливий тільки порядок аргументів.
- Щоб «зашити» свої значення заздалегідь, використайте замикання:
doLater(() => greet('Maria')). bindробить те саме через часткове застосування:greet.bind(null, 'Maria').- Колбек без дужок передається як посилання, дужки означають негайний виклик.
Швидкий приклад
function fetchData(callback) {
const data = 'Data from the server';
callback(data); // pass the parameter into the callback
}
function showData(info) {
console.log('Received:', info);
}
fetchData(showData);Вивід:
Received: Data from the serverСпосіб 1: виклик колбека з аргументами всередині функції
Це основний шлях. Ви передаєте сам callback, а приймальна функція сама вирішує, які дані йому дати і коли.
function processUser(action) {
const user = { name: 'Maria' };
action(user); // the receiving function supplies the argument
}
processUser(user => console.log(`Hello, ${user.name}!`)); // Hello, Maria!Імена параметрів у колбеку довільні: info, user, value, це просто локальні імена. Значення прив'язуються за позицією, тому важливий порядок, а не назви.
function withPair(callback) {
callback(1, 2);
}
withPair((a, b) => console.log(a, b)); // 1 2
withPair((first, second) => console.log(first, second)); // 1 2Спосіб 2: замикання, коли аргументи треба зафіксувати заздалегідь
Іноді приймальна функція нічого вам не передає (наприклад, setTimeout викликає колбек без аргументів), але ваші власні дані потрібні. Тоді загортаємо виклик у стрілкову функцію: вона замикає потрібні значення у своїй області видимості.
function doLater(callback) {
setTimeout(callback, 1000);
}
doLater(() => console.log('In one second!')); // the wrapper remembers the textfunction greet(name) {
console.log(`Hello, ${name}!`);
}
doLater(() => greet('Oleh')); // correct: the wrapper calls greet laterСпосіб 3: bind і часткове застосування
bind створює нову функцію з уже підставленими першими аргументами. Результат зручно передавати як callback.
function greet(greeting, name) {
console.log(`${greeting}, ${name}!`);
}
const sayHi = greet.bind(null, 'Hi'); // greeting is fixed
doLater(sayHi); // Hi, undefined! because doLater passes nothing
const sayHiToMaria = greet.bind(null, 'Hi', 'Maria');
doLater(sayHiToMaria); // Hi, Maria!| Прийом | Коли брати |
|---|---|
callback(data) всередині функції | Дані з'являються всередині приймальної функції: результат запиту, подія, елемент масиву |
| Стрілкова обгортка | Треба додати власні значення або змінити порядок аргументів |
bind | Потрібне часткове застосування або фіксація this для методу об'єкта |
Порядок аргументів у популярних API
Коли колбек передають у вбудований метод, порядок параметрів задає сам метод, і його треба знати.
[10, 20, 30].map((value, index, array) => value + index); // [10, 21, 32]
element.addEventListener('click', event => console.log(event.type)); // event is first
// error-first style: the error comes first, then the data
loadUser(7, (err, user) => {
if (err) {
console.error(err.message);
return;
}
console.log(user.name);
});Типові помилки
- Передавати
greet('Maria')як аргумент замість обгортки: функція виконається негайно, а приймальна функція отримаєundefined. - Писати
setTimeout(greet('Maria'), 1000)замістьsetTimeout(() => greet('Maria'), 1000). - Плутати позиції параметрів у вбудованих методах, наприклад брати
indexпершим аргументом уmap. - Забувати, що приймальна функція може викликати колбек взагалі без аргументів: тоді всі параметри будуть
undefined. - Передавати метод об'єкта як
obj.handlerі втрачатиthis. Використайтеobj.handler.bind(obj)або стрілкову обгортку. - Покладатися на
argumentsу стрілковій функції: у неї немає власногоarguments, беріть rest-параметри(...args).
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.