Обратные вызовы — это функции, которые передаются в качестве аргумента другим функциям. Эти обратные вызовы затем вызываются функцией, которой они переданы. Обычно мы передаем обратный вызов при использовании таких функций, как setTimeout()
и setTimeout()
.
Хотя обратные вызовы кажутся очевидными в своем использовании, они имеют присущий им недостаток. Этот пост посвящен этой проблеме, о которой я узнал недавно на курсе Кайла Симпсона на Frontend Masters.
Это пресловутый ад обратного вызова?
Первая мысль, которая приходит нам в голову при рассмотрении проблемы с обратным вызовом, — это ад обратного вызова. Однако это даже близко не похоже на проблему, с которой мы столкнулись.
Достаточно обрисовать ситуацию, теперь давайте перейдем непосредственно к ней. 😅
Инверсия управления
Википедия говорит об ИНК следующим образом:
В программной инженерии инверсия управления (IoC) — это принцип программирования. IoC инвертирует поток управления по сравнению с традиционным потоком управления. В IoC написанные на заказ части компьютерной программы получают поток управления от общей структуры. Архитектура программного обеспечения с таким дизайном инвертирует управление по сравнению с традиционным процедурным программированием.
Проще говоря, IOC — это передача управления потоком программы из наших рук какому-то внешнему коду.
Теперь давайте посмотрим, как это возможно с помощью обратного вызова.
Предположим, есть функция для отслеживания оформления заказа, которая принимает два аргумента, первый — информация о товаре, а второй — обратный вызов, который будет вызван, когда кто-то оформит заказ.
Вот как мы ее вызываем.
trackCheckout(purchaseInfo,function finish(){
chargeCreditCard(purchaseInfo);
showThankYouPage();
});
Проблема с передачей обратного вызова здесь в том, что его вызов не в наших руках. Мы передаем управление функции trackCheckout, которая предоставляется сторонним кодом.
Что если разработчик trackCheckout по ошибке вызовет наш обратный вызов таким образом?
function trackCheckout(options,callback){
process(option);
callback();
callback();//
}
Вы заметили, что наш обратный вызов теперь был выполнен два раза? Это означает, что теперь наши конечные пользователи будут получать плату дважды вместо одного раза, а это наименее ожидаемый опыт покупок.
Кроме того, может случиться так, что наш обратный вызов даже не будет вызван, что приведет к убыткам.
function trackCheckout(options,callback){
process(option);
//callback();
}
Итак, вот как обратный вызов приводит к инверсии управления, проблема заключается в обещании, о котором я расскажу как-нибудь в другом блоге.
Спасибо