Problem z użyciem "document.write()" wewnątrz pętli.

0

Przerabiam różne kursy na Treehouse. Obecnie "walczę" z JS. W jednym zadaniu wystąpił problem wynikający z wyświetlaniem danych w oknie przeglądarki przy pomocy polecenia wymienionego w temacie. Treehouse jest obecnie w trakcie przygotowania nowej wersji video w tej sprawie.
O co chodzi.. Przeglądarki (za wyjątkiem FF) nie wyświetlają danych przy pomocy tego polecenia w czasie trwania pętli, dopiero po jej zakończeniu. Powoduje to "cache" wpisanych danych i wypisanie ich (wszystkich) dopiero gdy pętla zostanie zakończona.
Przykładowo mamy podać w oknie (prompt()) jakiś element do wyszukania w zdefiniowanej w programie tablicy. Nastąpi wtedy wyświetlenie odpowiedzi czy ten element jest lub czy go nie ma. Mamy też możliwość wyświetlenia całej zawartości tablicy (np. przy pomocy tablica.join(',')). No i oczywiście możemy wpisać polecenie przerywające działanie pętli (np. przy pomocy break (pętla nieskończona)). Niestety dane zostają wyświetlane dopiero po wpisaniu polecenia kończącego działanie pętli. Można wpisać 20 razy "auto" i nic nie ma , a w momencie wyjścia wyświetli 20 razy odpowiednią opcję z argumentem "auto". Zaznaczam, że nie poszukiwałem jeszcze odpowiedzi na SO, gdyż lecę dalej z materiałem zanim zasnę :)

Oczywiście pytam o rozwiązanie bez użycia DOM.

0

Samo document.write możesz olać. I tak się tego już nie używa (no chyba, że do mocnej hakerki typu osadzanie zewnętrznych skryptów, ale i w to wątpię, bo zdaje się, że i tak można zrobić document.body.appendChild, ale kto wie...)

Swoją drogą nie napisałeś w zasadzie, gdzie leży twój problem. Masz pretensje do JSa, że działa jak działa?

Przeglądarki (za wyjątkiem FF) nie wyświetlają danych przy pomocy tego polecenia w czasie trwania pętli, dopiero po jej zakończeniu.
Powoduje to "cache" wpisanych danych i wypisanie ich (wszystkich) dopiero gdy pętla zostanie zakończona.

Nie wiem, czy w tym przypadku tak jest, ale to zachowanie, o którym piszesz jest typowe dla rzeczy, które są odpalane w JS asynchronicznie.

Tu jest fajne wideo, które to tłumaczy:

0

Dzięki, na pewne zaraz obejrzę :) Po prostu uczę się i na bieżąco szukam odpowiedzi. Lekcja ma być poprawiona, ale byłem ciekaw już teraz więc zadałem pytanie :) W następnej lekcji, jest wyjaśnione, iż obecnie używa się DOM, a nie sposobu z końca lat 90-ych :)

var inStock = [ 'apples', 'eggs', 'milk', 'cookies', 'cheese', 'bread', 'lettuce', 'carrot', 'broccoli', 'pizza', 'potato', 'crackers', 'onion', 'tofu', 'frozen dinner', 'cucumber'];
var search;

function print(message) {
  document.write( '<p>' + message + '</p>');
}

while (true) {
  search = prompt("Search for a product in our store. Type 'list' to show all of the produce and 'quit' to exit");
  search = search.toLowerCase();
  if ( search === 'quit') {
    break;
  } else if ( search === 'list' ) {
    print( inStock.join(', ') ); 
  } else {
    if ( inStock.indexOf( search ) > -1 ) {
      print( 'Yes, we have ' + search + ' in the store.');
    } else {
      print( search + ' is not in stock.'); 
    }
  }
}

Wynik jak poniżej pojawi się dopiero po wpisaniu "quit", a tak strona jest pusta. W FF wynik pojawia się pod oknem "prompt" na bieżąco

Chrome:
screenshot-20171204234007.png

FF:
screenshot-20171204234038.png

0

Jeśli chcesz sprawić, by asynchroniczna akcja wykonywała się synchronicznie, to tego nie zrobisz. Możesz natomiast to zasymulować (wymusić pożądaną kolejność) przez dodanie jeszcze więcej asynchroniczności, poniżej przykład wypisywania liczb:

const go = (i) => {
  if (i <= 1000) {
    document.write(i + ' ')
    setTimeout(go, 0, i + 1)
  }
}

go(0)

CodePen: https://codepen.io/caderek/pen/wPOYjx?editors=0010

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