Nie jestem pewien, czy moje pytanie jest subiektywne / obiektywne, ale jako javascript Newbie spotykam ten problem. Więc tu idę.

Jestem przyzwyczajony do pisania C #, więc moja konstrukcja JavaScript wygląda jak C #. I tak, że to daje problemy, myślę ;-) Dajmy prosty przykład, w którym znów spotkałem mój problem:

MyLibrary.fn.InitAddEntityForm = function () {
    $('a#btnAddEntity').click(function () {
            //post data and receive object with guid and isPersisted boolean
            var persistedObject = MyLibrary.fn.CheckAndSendAddEntityForm("name", "avatarurl.png");
            console.log("test");

            //check if persisted and go to next step
            if (persistedObject.isPersisted) {
                MyLibrary.fn.InitAddAnotherEntityForm(persistedObject.gdEntityId);
            } else {
                alert("Oops, something went wrong. Please call 911");
            }
    });
};


//////*****/////
//SOME FUNCTION THAT SENDS MY FORM AND RETURNS AN OBJECT WITH TRUE VALUE AND POSTED ENTITY ID
/////*****//////
MyLibrary.fn.CheckAndSendAddForm = function (txtName, ImageUrl) {
var postUrl = "/admin/add";
var persistedObject = new Object();
$.post(
    postUrl,
    { Name: txtName, ImageUrl: txtImageUrl},
    function (data) {
        if (data.Status == 200) {
            console.log("Post status:" + data.Message);
            persistedObject.isPersisted = true;
            persistedObject.gdEntityId = data.Data;
        } else if (data.Status == 500) {
            console.log("Failed to post entitiy");
        } else {
            console.log("Fault with Javascript");
        }
    }, "json"
);
return persistedObject;

};

Dobra, to jest. Wszystko wygląda dobrze? Przeglądarka mówi nie. Próbowałem debugować go za pomocą Firebug, zapętląc się przez linię kodu według linii, a w ten sposób przeglądarka robi to, czego chcę: Wykonaj nową funkcję, aby pokazać następny panel w moim kreatorze.

Po umieszczeniu wielu konsoli.logs () w moim kodzie pomyślałem, że musi to być coś o czasie w JavaScript. W C # kod wykonuje linię według linii, ale najwyraźniej JavaScript nie. Umieszczając tę konsolę.log ("Test") zauważyłem, że "test" pojawił się w mojej konsoli przed "statusem postu: sukces!".

Oto moje pytanie, jak powinienem pisać mój kod JavaScript, więc mam kontrolę nad drogą, w jaki przeglądarka wykonuje mój kod? Czy naprawdę powinienem zastąpić poniższy kod na końcu mojej kontroli CheckandsendaddentityForm ()?

//check if persisted and go to next step
        if (persistedObject.isPersisted) {
            MyLibrary.fn.InitAddAnotherEntityForm(persistedObject.gdEntityId);
        } else {
            alert("fout");
        }

Czy to w jaki sposób muszę napisać JavaScript: jeden duży efekt domino lub czy mogę coś robić coś złego?

2
Gigi2m02 21 sierpień 2012, 02:10

4 odpowiedzi

Najlepsza odpowiedź

$ .post jest skrótem dla połączenia AJAX, AJAX jest z definicji asynchroniczny, co oznacza, że nie będzie czekać na odpowiedź przed kontynuowaniem przetwarzania. Jeśli przełączysz go do regularnej metody AJAX (), istnieje opcja asynchronizacji, którą można ustawić na false, co sprawi, że będzie się zachowywać, jak się spodziewasz.

Alternatywnie można również zdefiniować funkcję do wykonania w odniesieniu do udanego zwrotu żądania AJAX, w którym można wywołać następny krok w łańcuchu procesowym.

3
invertedSpear 20 sierpień 2012, 22:15

Call ajax jest asychroniczne; Oznacza to, że metoda zwrotna eksponuje przez $.post zostanie wykonana, gdy żądanie zakończy się, ale twój JavaScript będzie kontynuował wykonywanie, jak tylko wywołanie wywoływania $.post. Jeśli chcesz coś zrobić po zakończeniu połączenia Ajax, musisz podać metodę wywołania zwrotnego i zrobić coś innego, np.:

MyLibrary.fn.CheckAndSendAddForm = function (txtName, ImageUrl, callback) {
var postUrl = "/admin/add";
var persistedObject = new Object();

$.post(
    postUrl,
    { Name: txtName, ImageUrl: txtImageUrl},
    function (data) {
        if (data.Status == 200) {
            console.log("Post status:" + data.Message);
            persistedObject.isPersisted = true;
            persistedObject.gdEntityId = data.Data;
        } else if (data.Status == 500) {
            console.log("Failed to post entitiy");
        } else {
            console.log("Fault with Javascript");
        }

        callback(); // This is where you return flow to your caller
    }, "json"
);
};

Potem się przywołujesz:

var persistedObject = MyLibrary.fn.CheckAndSendAddEntityForm("name", "avatarurl.png", function()
{
        console.log("test");

        //check if persisted and go to next step
        if (persistedObject.isPersisted) {
            MyLibrary.fn.InitAddAnotherEntityForm(persistedObject .gdPronoId);
        } else {
            alert("Oops, something went wrong. Please call 911");
        }
});
1
Tejs 20 sierpień 2012, 22:18

JavaScript jest pojedynczy gwintowany. Jeśli masz funkcjonalność asynchroniczną, prosty boolean Semafore zmienna pomoże nie zezwolić na inwokacje funkcji podczas pracy niektórych procesów.

Jeśli chcesz wykonać zadania asynchroniczne jeden po drugim (jak linia domino), będziesz musiał użyć funkcji zwrotnych.

0
Bergi 20 sierpień 2012, 22:17

Spotkanie jest "asynchroniczny" kawałek AJAX. Jeśli chcesz fizycznie (jak w linii linii według linii w pliku JavaScript) możesz użyć metod .success, .pipe lub {X2}}} lub {x2}} . Nie osadzaj zwrotów zwrotów, jeśli możesz sobie pomóc, lub ty będzie uzyskać "efekt domina", jak nazywasz go.

0
JayC 20 sierpień 2012, 22:20