javascript-de-callback-ler--1-ci-hisse

Javascript-də callback-lər: 1-ci hissə

Full-Stack developer olaraq işlədiyim yerlərdə native Javascript(bundan sonra JS) istifadə edərək yeni modulların yaradılması, mövcud sistemin müşayiət olunması kimi məsələlərlə məşğul olmaq mənə təcrübədə əvəzolunmaz biliklər qazandırıb. Bu isə Javascriptin bir çox konstruksiyalarının praktikada nə işə yaradığını başa düşməyimə çox böyük köməklik edib. Bu məqalədən etibarən saytımızda təkcə .NET platforması üzrə yox, həmçinin Javascript üzrə də bir çox təcrübələrimizi sizinlə paylaşacağıq. Bu məqalələr JS-in daxili strukturunu daha yaxşı başa düşməyinizə imkan verəcək.

               Saytımızın JS-lə bağlı ilk məqaləsi, bir çoxlarının  çətinlik çəkdiyi callback-lər olacaq.(kolbək) Callback-lər praktikada çox istifadə olunur. Hansısa bir JS kitabxanası istifadə etsəniz belə, ən çox isifadə edəcəyiniz JS mövzularından biri callback-lər olacaq.

Hər şey əslində funksiyalardan başlayır....

               Proqramlaşdırma dillərində funksiyalar mövzusu bizə təkrar istifadə olunan kod blokları yaratmağa imkan verir. Funksiyaları istifadə edərkən onlara parametr ötürərək kod blokunun təkrar istifadə olunmasını təmin etmək olur.

   function add(a, b) {
            return a + b;
        }

Burada a və b arqumentlərinin yerinə istənilən bir qiyməti verdikdə belə proqram düzgün hesablama aparır. Bu cür yanaşma ilə riyaziyyatdakı bir növ düstur anlayışı formalaşır və eyni sinifdən olan (burada toplama sinifi) əməliyyatları təkrar-təkrar yazmaqdan xilas olunuq. Lakin funksiyaların elə formaları var ki, onlara sadəcə dəyişən-parametr ötürmək kifayət etmir. Bəzən kod bloklarını daha kiçik hissələrə ayırıb təkrar istifadəni təmin etmək və bunu dinamik şəkildə idarə edə bilmək üçün bir funksiyaya arqument olaraq başqa bir funksiyanı ötürmək lazım gəlir.

Bəs nədir axı callback-lər?

Callback funksiyaya arqument olaraq başqa bir funksiyanın ötürülməsi prosesidir. Bir funksiyaya başqa bir funksiyanı ötürmə ehtiyacı nədən yarana bilər və ya callback nə işə  yarıyır?

Bu suala cavab vermək üçün ən bəsit şəkildə massivlər üzərində axtarış alqoritminə baxaq.  JS-in öz default axtarış funksiyasına müraciət etmədən massivdə axtarış prosesinin necə yerinə yetirildiyinə addım-addım baxaq.

Tapşırıq: 45,56,103,91,405, 324 rəqəmlərindən ibarət bir massiv verilmişdir. Bizə bu massivdə 50-dən böyük ədədlərin tapılması lazımdır.

 let array = [45, 56, 103, 91, 405, 324];


        function findInArray(arr) {
            let result = [];
            for (let f of arr) {
                if (f > 50) {
                    result.push(f);
                }
            }
            return result;
        }

Bir müddətdən sonra proqramın başqa hissəsində eyni massiv üzərində (və ya başqa massiv ola bilər) başqa şərt ilə (misal 100dən böyük və 200-dən kiçik ədədlərin tapılması) elementlərin axtarılması lazım olur. Belə olan haqda alqoritmlərdə öyrəndiyimiz üzrə yazdığımız kod alqoritmin kütləvilik xassəsinə riayət etməlidir. Kütləvilik xassəsində deyilir ki, alqoritm bir sinifdən olan bütün məsələlərin həlli üçün doğru olmalıdır. Bu o deməkdir ki, sən əgər bir massiv üçün hansısa bir şərtdə axtarış verirsənsə başqa bir şərt üzrə axtarış verən zaman 0-dan alqoritm yazmamalısan! Yazdığın bir əvvəlki alqoritm artıq bütün axtarış şərtlərini ödəməlidir. Amma  yuxarıda olan axtarış funksiyası bizim tələbi ödəmir. Səbəb: Yazılan kod genişlənə bilən kod deyil. Indi bu alqoritmin bütün axtarış şərtlərinə cavab verməsini təmin edək.

İlk cəhd...

 let array = [45, 56, 103, 91, 405, 324];


        function findInArray(arr, findNum) {
            let result = [];
            for (let f of arr) {
                if (f > findNum) {
                    result.push(f);
                }
            }
            return result;
        }

Kodun təkrar istifadə olunma ehtimalı : 0-10%

İlk cəhdimizdə axtarılan ədədin funksiyaya arqument olaraq ötürülməsinə baxacağıq. Ədədi rahatlıqla dəyişmək olsa da şərti dəyişmək mümkün olmur. Rəqəmi dəyişmək imkanımız olduğuna görə kodun təkrar istifadə olunma faizini 0-10% olaraq götürək.

İkinci cəhd.. şərt operatorunun arqumentə çıxarılması

let array = [45, 56, 103, 91, 405, 324];


        function findInArray(arr, findNum, op) {
            let result = [];
            for (let f of arr) {
                switch (op) {
                    case '>':
                        {
                            if (f > findNum) {
                                result.push(f);
                            }
                        }
                        break;
                    case '<':
                        {
                            if (f < findNum) {
                                result.push(f);
                            }
                        }
                        break;
                    case '>=':
                        {
                            if (f >= findNum) {
                                result.push(f);
                            }
                        }
                        break;


                }


            }
            return result;
        }

Şərt operatorunu arqumentə çıxardaraq kodun təkrar istifadəsinə təxmini olaraq 30-35% nail ola bilərik amma bu kod da genişlənmə baxımından çox zəif, “relizə çıxarılmayacaq” bir koddur. Səbəb ondan ibarətdir ki, əgər ikili şərtlər olarsa (misal 100dən böyük amma 300dən kiçik ədədlərin tapılması) funksiya bizim tələbatı ödəmir.Həmçinin tələbdən asılı olaraq yeni şərtlər əlavə etmək lazım olacaq. Bəs necə edək ki, yazılan funksiya bütün axtarış tələbatını ödəyə bilsin?

 Söz callback-lərdədir və ya “gör indi qaqan nağarajax?”

               Məsələni kütləvilik xassəsinə uyğun yerinə yetirə bilmək üçün şərt blokunu ümumiyyətlə funksiyasının içərisindən çıxardıb arqumentə yazmaq lazımdır. Amma proqramlaşdırma dilində if blokunu birbaşa funksiyaya arqument olaraq ötürmək olmur.. Bunu aradan qaldırmaq üçün if blokunu ayrica bir funksiyaya çıxardıb həmin funksiyanı arqument olaraq əsas funksiyaya ötürmək lazımdır.

Kod burada

Beləliklə funksiya arqument olaraq callback alır və bununla istənilən bir funksiyanı bu funksiyaya arqument kimi ötürə bilərik.

 let array = [45, 56, 103, 91, 405, 324];


        function findInArray(arr, callback) {
            let result = [];
            for (let f of arr) {
                if (callback(f)) {
                    result.push(f);
                }
            }
            return result;
        }


        //her bir emeliyyati ayrica funksiyaya cixardiriq
        function ifLessFrom50(num) {
            return num < 50;
        }


        //her bir emeliyyati ayrica funksiyaya cixardiriq
        function ifGreaterThan50(num) {
            return num > 50;
        }


        //ifLessFrom50 funksiyasini findInArray funksiyasina birbasa  arqument olaraq otururuk
        let ls = findInArray(array, ifLessFrom50);
        console.log(ls);


        //funksiyaya argument olaraq birbasa anonim funksiya otururuk
         //anonim funksiya burada callbackdir
         let nextResult = findInArray(array, function(x) {
            return x > 50 && x < 200;
        });
        console.log(nextResult);


        //hemcinin funksiyaya argument olaraq lambda ifade oture bilirik
       //lambda ifade(narrow function) burada callback-dir.
          let result = findInArray(array, x => x > 50 && x < 300);
        console.log(result);

Əgər yazacağımız şərt kod blokunu birdən artıq yerdə istifadə edəcəyiksə ozaman həmin blokları ayrıca funksiyalara çıxartmaq məqsədə uyğundur.

  //her bir emeliyyati ayrica funksiyaya cixardiriq
        function ifLessFrom50(num) {
            return num < 50;
        }


        //her bir emeliyyati ayrica funksiyaya cixardiriq
        function ifGreaterThan50(num) {
            return num > 50;
        }


Əgər verilən funksiya sadəcə bu konteks daxilində lazımdırsa ozaman anonim funksiya və ya lambda ifadələrdə istifadə edə bilərik.

  //funksiyaya argument olaraq birbasa anonim funksiya otururuk
         //anonim funksiya burada callbackdir
         let nextResult = findInArray(array, function(x) {
            return x > 50 && x < 200;
        });
        console.log(nextResult);


        //hemcinin funksiyaya argument olaraq lambda ifade oture bilirik
       //lambda ifade(narrow function) burada callback-dir.
          let result = findInArray(array, x => x > 50 && x < 300);
        console.log(result);

Birinci hissənin yekunu olaraq deyə bilərik ki,Callback-lər funksional blokun funksiyaya arqument olaraq ötürülməsini təmin etmək üçündür. Məqaləmizin ikinci hissəsində callbacklərin praktiki istifadə aspektlərinə nəzər yetirəcək, 3-cü hissədə isə öz callback modulumuzu yazacağıq.

Tural

Tural Süleymani

Süleymani Tural Microsoft-un MCSD statuslu mütəxəssisidir, 2008-ci ildən bu yana proqramlaşdırma üzrə tədris aparır

Müəllifin bu dildə ən son postları

Bu yazıları da bəyənə bilərsiniz