Какво представлява функцията за обратно извикване в JavaScript?

Тази статия дава кратко въведение в концепцията и използването на функциите за обратно извикване в езика за програмиране JavaScript.

Функциите са обекти

Първото нещо, което трябва да знаем, е, че в Javascript функциите са първокласни обекти. Като такива можем да работим с тях по същия начин, по който работим с други обекти, като да ги присвоим на променливи и да ги предадем като аргументи в други функции. Това е важно, тъй като именно последната техника ни позволява да разширим функционалността на нашите приложения.

Функции за обратно извикване

Функцията за обратно извикване е функция, която се предава като аргумент на друга функция, за да бъде „извикана обратно“ по-късно. Функция, която приема други функции като аргументи, се нарича функция от по-висок ред , която съдържа логиката за това, кога функцията за обратно извикване се изпълнява. Комбинацията от тези две ни позволява да разширим функционалността си.

За да илюстрираме обратно извикване, нека започнем с прост пример:

function createQuote(quote, callback){ var myQuote = "Like I always say, " + quote; callback(myQuote); // 2 } function logQuote(quote){ console.log(quote); } createQuote("eat your vegetables!", logQuote); // 1 // Result in console: // Like I always say, eat your vegetables!

В горния пример createQuoteе функцията от по-висок ред, която приема два аргумента, вторият е обратното повикване. Най logQuoteфункция се използва, за да премине в по нашата функция за обратно извикване. Когато изпълняваме createQuoteфункцията (1) , забележете, че не добавяме скоби, logQuoteкогато я предаваме като аргумент. Това е така, защото не искаме да изпълним нашата функция за обратно извикване веднага, просто искаме да предадем дефиницията на функцията на функцията от по-висок ред, за да може да бъде изпълнена по-късно.

Също така трябва да гарантираме, че ако функцията за обратно извикване, която предаваме, очаква аргументи, че ние ги предоставяме при изпълнението на обратното повикване (2) . В горния пример това би било callback(myQuote);изявлението, тъй като знаем, че logQuoteочаква да бъде предадена оферта.

Освен това можем да предадем анонимни функции като обратно извикване. Извикването по-долу createQuoteще има същия резултат като горния пример:

createQuote("eat your vegetables!", function(quote){ console.log(quote); });

Между другото, не е нужно да използвате думата „callback“ като име на вашия аргумент, Javascript просто трябва да знае, че това е правилното име на аргумента. Въз основа на горния пример, функцията по-долу ще се държи по абсолютно същия начин.

function createQuote(quote, functionToCall) { var myQuote = "Like I always say, " + quote; functionToCall(myQuote); }

Защо да използвам функциите за обратно извикване?

През повечето време създаваме програми и приложения, които работят по синхронен начин. С други думи, някои от нашите операции започват само след като приключат предходните. Често, когато искаме данни от други източници, като външен API, не винаги знаем кога данните ни ще бъдат върнати обратно. В тези случаи искаме да изчакаме отговора, но не винаги искаме цялото ни приложение да се спира, докато нашите данни се извличат. Тези ситуации са, когато функциите за обратно извикване са полезни.

Нека да разгледаме пример, който симулира заявка към сървър:

function serverRequest(query, callback){ setTimeout(function(){ var response = query + "full!"; callback(response); },5000); } function getResults(results){ console.log("Response from the server: " + results); } serverRequest("The glass is half ", getResults); // Result in console after 5 second delay: // Response from the server: The glass is half full!

В горния пример правим фиктивна заявка към сървър. След изтичане на 5 секунди отговорът се променя и след това нашата функция за обратно извикване getResultsсе изпълнява. За да видите това в действие, можете да копирате / поставите горния код в инструмента за разработчици на вашия браузър и да го изпълните.

Освен това, ако вече сте запознати setTimeout, тогава през цялото време сте използвали функции за обратно извикване. Аргументът за анонимна функция, предаден в setTimeoutизвикването на функцията на горния пример, също е обратно повикване! Така че оригиналният обратно извикване на примера всъщност се изпълнява от друг обратен разговор. Внимавайте да не гнездите твърде много обратно извикване, ако можете да му помогнете, тъй като това може да доведе до нещо, наречено „ад на обратно обаждане“! Както подсказва името, не е радост да се занимаваш.