Zakończenie metody za pomocą return w podrzędnym ajax

Odpowiedz Nowy wątek
2015-12-30 12:06

Rejestracja: 4 lata temu

Ostatnio: 3 lata temu

0

Witam wszystkich,

Piszę sobie właśnie dla przećwiczenia wiedzy prostą aplikacje z wykorzystaniem ajax. Obecnie jestem na etapie implementacji mechanizmu uwierzytelnienia, ale mam problem, który prawdopodobnie wynika z nie zrozumienia pewnych zasad rządzących programowaniem asynchronicznym.

Otóż kiedy użytkownik klika sobie na stronie w przycisk 'zaloguj', wywołuje metodę, która zmienia widoki (template). Na razie działa to na zasadzie ukrywania i pokazywania równorzędnych div w jednym html (później prawdopodobnie przerzuce je do osobnych plikow html i bedę robił injection). Jeśli kliknę w ten specyficzny przycisk, który ma mnie przenosić do widoku wymagającego autoryzacji, to wcześniej w tej metodzie uruchamiam inną metodę odpowiadającą za uwierzytelnienie.

Uwierzytelnienie, może mieć kilka scenariuszy, albo hasło i login się zgadzają i metoda uwierzytelniania nie robi nic, albo jakieś dane nie pasują i chciałbym, żeby w tym momencie podrzędna metoda uwierzytelniania przerywała nadrzedną(w której jest umieszczona) metodę ładowania widoków. O ile gdy np. w bloku if else umieszcze gdzieś sobie return false i wszystko działa po mojej myśli, o tyle z osiągnięciem tego efektu w funkcji asynchrinicznej jest problem. Próbowałem ze standardową funkcją ajax i paramtrem async: false, próbwałem również bawić sie z obiektem deffered, ale efekt zawsze był ten sam - return nie wykonywał się.

Metoda do zmiany widoków:

changeView(el, wait, time, displayType){
        var newView = '';

        if(el === 'work'){
            if(actions.authentication() == false){
                return false;
            }
        }

            el !== 'last' ? (
            newView = `#${el}-view`
            ) : (
                newView = `#${params.lastView}`
            );

            setTimeout(function(){
                $('.view').animate({opacity: 0}, time);
            }, wait);
            setTimeout(function(){
                $('.view').css('display', 'none');
            }, wait+time);
            setTimeout(function(){
                $(newView).css('display', displayType).animate({opacity: 1}, time); 
            }, wait+time)   
    }

Metoda do weryfikacji:

authentication(){
        var userLogin = $('#user-login').val(),
        userPassword = $('#user-password').val(),
        usersJson = "";

        try{    
            if(userLogin && userPassword){
                $.getJSON('js/users.json', function(data){
                    var usersJson=data.users,
                    userJsonLength = data.users.length,
                    i=0,
                    def = $.Deferred();

                    for(let prop of usersJson){
                        i++;
                        if(prop.login === userLogin){
                            alert(`Find that user in Json!`);
                        }
                        else{
                            if(i==userJsonLength){
                                //return false - ten nie wykona sie, bo jest wewnatrz ajax;
                                alert('Incorrect user');    
                            }

                        }
                    }

                })

                //return false - ten return przerwie metode changeView - jest poza ajax;
            }
            else{
                throw ("Empty fields");

            }
        }
        catch(err){
            alert(err);
            return false;
        }   

    }

Pozostało 580 znaków

2015-12-30 13:04
Moderator

Rejestracja: 13 lat temu

Ostatnio: 2 miesiące temu

Lokalizacja: Rzeszów

1

Tu nie chodzi o asynchroniczność, tylko o przekazywanie callbacków i/lub funkcje anonimowe. Robisz coś takiego:

var niby_ajax = function(url, callback) {
  // costam synchronicznego, żeby pokazać, że synchroniczność nie ma tu nic do rzeczy

  callback();
  return 5;
}

var twoj_callback = function() {
  return false;
}

var wynik = niby_ajax('niewazne', twoj_callback);

// równoznaczne, funkcja anonimowa:
var wynik = niby_ajax('niewazne', function() {
  return false;
});

Z jakiegoś powodu oczekujesz, że dla powyższego kodu wynik będzie false, a nie 5 ;)
Ty do ajaxa przekazujesz funkcję, którą ajax na końcu wykonuje, ale jej wynik nie jest nigdzie wykorzystywany.

Niestety cieżko dokładniej odnieść się do Twojego problemu, bo w nim nie widać nawet wywołania funkcji changeView ;)

PS. Używasz TypeScripta albo ES6, to dlaczego nie używać natywnych Promises zamiast Deferredów?


edytowany 3x, ostatnio: dzek69, 2015-12-30 13:05

Pozostało 580 znaków

2016-01-09 11:17

Rejestracja: 4 lata temu

Ostatnio: 3 lata temu

0

@dzek69
Ok, trochę mi rozjaśniłeś sytuacje ;). Przebudowałem nieco strukturę kodu i efekt udało mi się osiągnąć bez angażowania deffered czy promise.

deffered używałem kilka razy i byłem do niego przyzwyczajony, ale rzeczywiście będzie się trzeba przestawić na promise.

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0