Synchroniczne oddczytanie zmiennej z domknięcia Ajax

0

Jest zmienna fileContent która jest modyfikowana wewnątrz Ajaxa.
Niestety nie widzę tej zmiennej na zewnątrz kodu Ajax'a.

var fileContent = "";

$.ajax({
  method: "POST",
  url: "php/plik.php",
  data: {"nazwa": "nazwa"},
  }).done(function( data ) {
        var result = $.parseJSON(data);
        if (result!== null){
            var len = result.length;
                for(var i=0; i<len; i++){
                    fileContent=fileContent+result[i].nazwa+";";
                    fileContent=fileContent+(result[i].komentarz)+"\n";
                }
            }
        }
);

console.log(fileContent); //  <--- tutaj chciałbym aby zmienna fileContent była widoczna (a nie jest)

Czy mógłby ktoś na tym przykładzie zmodyfikować tak kod żeby zmienna fileContent była widoczna poza kodem Ajax'a?

Wielkie dzięki za pomoc.

2

To co wkleiłeś wydaje się być działającym kodem. Jednak lepiej poczytaj o zasięgu zmiennych w JS np.
https://www.w3schools.com/js/js_scope.asp
I zobacz czy jednak nie deklarujesz zmiennych w zakresie jakiejś funkcji.

1
var fileContent = ""; // To wykona się jako pierwsze

$.ajax({ // Ten cały ajax zostanie wykonany jako OSTATNI wraz z metodą DONE, bo jest asynchroniczny
  method: "POST",
  url: "php/plik.php",
  data: {"nazwa": "nazwa"},
})
.done(function( data ) {
  var result = $.parseJSON(data);
  
  if (result!== null){
    var len = result.length;
  
    for(var i=0; i<len; i++){
      fileContent=fileContent+result[i].nazwa+";";
      fileContent=fileContent+(result[i].komentarz)+"\n";
    }
  }
});

console.log(fileContent); // console.log zostanie wykonany jako drugi

Żeby naprawić problem asynchroniczności, który opisałem w komentarzach musisz przenieść console.log do metody done, albo owinąć wszystko w obiekt promise, w podobny sposób jak tutaj https://stackoverflow.com/questions/35135110/jquery-ajax-with-es6-promises
i korzystać z tego jak z normalnego promisa.

0

@jurek1980: czy miałeś coś konkretnego na myśli pisząc o sposobie deklaracji zmiennych? Przeglądnąłem dokument który podesłałeś i nie widzę błędu... no ale może już za długo patrzę na ten kawałek kodu... próbowałem ze zmiennymi różnego typu i nic to nie pomogło :(

4
bzc0fq napisał(a):

Jest zmienna fileContent która jest modyfikowana wewnątrz Ajaxa.
Niestety nie widzę tej zmiennej na zewnątrz kodu Ajax'a.

Nie ma czegoś takiego jak "wewnątrz Ajax'a". Być może chodzi Ci o "wewnątrz domknięcia"?

Czy mógłby ktoś na tym przykładzie zmodyfikować tak kod żeby zmienna fileContent była widoczna poza kodem Ajax'a?

Nie da się, i nie powinno.

Po pierwsze, ten kod jest asynchroniczny, czyli jeśli wyślesz żądanie, to ono zostanie obsłużone po około 50-2000ms, zależnie od tego gdzie strzelasz i na jakim urządzeniu jest. Cały JavaScript jest obudowany na takiej zasadzie, asynchronicznych wywołań.

Najbliższe co moim zdaniem możesz zrobić, to:

$.ajax({
  method: "POST",
  url: "php/plik.php",
  data: {"nazwa": "nazwa"},
  }).done(function (data) {
        const result = $.parseJSON(data);
        let fileContent;
        if (result!== null){
            var len = result.length;
                for(var i=0; i<len; i++){
                    fileContent=fileContent+result[i].nazwa+";";
                    fileContent=fileContent+(result[i].komentarz)+"\n";
                }
            }
        }
        fileLoaded(fileContent);
);

function fileLoaded(fileContent) {
  console.log(fileContent); //  <--- tutaj chciałbym aby zmienna fileContent była widoczna (a nie jest)
}

Po drugie, widać że piszesz kod w całości w "mainie", czyli jako linie poleceń wywoływane prosto z "pliku", nie porozdzielane na funkcje. To jest ogólnie zła praktyka, i powinieneś je porozdzielać tak czy tak.

PS: Oczywiście zaraz wyskoczą na mnie fanboye, że przecież jest await i async - owszem jest; ale await'a można użyć tylko w async function, której pytający tutaj nie ma; a poza tym i tak trzeba zrozumieć co to jest asynchroniczny kod żeby używać async/awaitów.

4

Tak. Koledzy tu dobrze gadają. Mnie nie słuchaj :)

0

@TomRiddle: OK. Rozumiem... a właściwie coś zaświtało ;) Musiałem trochę przemodelować kod, ale teraz działa.
Dzięki za pomoc! Pozdrowienia.

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