Pewnie było sto razy - wyciąganie danych z async/ await

Pewnie było sto razy - wyciąganie danych z async/ await
KR
  • Rejestracja:ponad 6 lat
  • Ostatnio:około rok
  • Postów:83
0

Cześć, zaciąłem sie na czymś co pewnie jest proste, tyle, że nie dla mnie.
To, co poniżej to dwie (z wielu) metod klasy. Pierwsza - remoteLoad ma zerealizowac pobranie danych z zewnętrznego źródła, druga -getData- natomiast ma zrealizować takie pobranie i zwrócić dane. w sytuacji kiedy w storage nie ma danych. Jak sie zapewne domyślacie ostatecznie zwracana jest Promise co jest niepożądan, chciałbym mieć konkretna wartość.
Oczysiście w zakresie remoteLoad mam dostęp do właściwych wartości co sobie sprawdzam przez console.log(resp). Tyle, że potrzebuję tych wartości poza nią a nie w niej. Niemożliwe, żeby to nie było realizowalne, jednak wypróbowałem kilka sposobów - prostsze tj. praca na czystych promise, bardziej zaawansowane - axios i jeszcze trochę innych a nie jestem bliżej. Nie miałbym pewnie problemu z wykonaniem jakiejś funkcji na tych danych w zakresie try, ewentualnie pewnie dałoby się zapisac w jakims sztucznym stanie, ale ja to potrzebuję tego po prostu na zewnątrz w takim ukladzie mniej wiecej jak napisałem.

Kopiuj
async remoteLoad(){
var that = this;
var result = null;
    try {
        const x = await fetch('https://api.myjson.com/bins/amapk');
        const resp = await x.json();
        console.log (resp);
        return resp;
        }

        catch(e){console.log(e)}
   
}

getData() {
    return this.storageService.areInStorage() ? this.storageService.load('localBooks') : this.remoteLoad();
}
KR
Oczywiście w getData funkcja nie musi być tożsama z this.remoteLoad, jednak ta funkcja w getData musi być funkcja i zwracać to o czym napisałem. I ja naprawdę nie wiem jak to ugryźć
Pafker
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 5 lat
  • Postów:17
0

Po pierwsze po co Ci w funkcji remoteLoad() te linijki:

Kopiuj
var that = this;
var result = null;

A po drugie nie mowisz gdzie chcesz wykorzystac ta wartosc resp.
Zauzmy, ze w getData()

Kopiuj
async getData(){
let resp = await remoteLoad();
}

Przeciez ta funkcja zwraca ci wartosc resp, wiec ja przypisz do zmiennej

edytowany 1x, ostatnio: Pafker
KR
  • Rejestracja:ponad 6 lat
  • Ostatnio:około rok
  • Postów:83
0

Dzieki. Te linijki to pozostałości po pórbach róznego rodzaju
Ale funkcja nie zwraca wartości tylko promise i to jest cały ból - sorry, że o tym nie napisałem, byłoby lepie widać z czym walczę

edytowany 1x, ostatnio: Krajeski
Pafker
Straszny chaos w opisie problemu :D Nastepnym razem krocej ale konkretniej
KR
Uwierz na słowo, że to skrócona wersja, mama tendencję do barokowo rozlazłeych opisów i komentarzy
Patryk27
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
0
Kopiuj
async getData() {
    return this.storageService.areInStorage() ? this.storageService.load('localBooks') : await this.remoteLoad();
}

KR
  • Rejestracja:ponad 6 lat
  • Ostatnio:około rok
  • Postów:83
0
Patryk27 napisał(a):
Kopiuj
async getData() {
    return this.storageService.areInStorage() ? this.storageService.load('localBooks') : await this.remoteLoad();
}

Wyrzuca błąd SyntaxError: await is only valid in async functions and async generators

Patryk27
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
0

Na pewno masz w swoim kodzie async getData(), tak jak napisałem?


edytowany 1x, ostatnio: Patryk27
KR
  • Rejestracja:ponad 6 lat
  • Ostatnio:około rok
  • Postów:83
0
Patryk27 napisał(a):

Na pewno masz w swoim kodzie async getData(), tak jak napisałem?

Przyznaję, że nie miałem, ale jak mam to znowu zwraca promise Dopisże gdzie to widać :

Kopiuj

  const egz = new ListModel; console.log(egz.getData())
  
  
  

listModel to nazwa klasy którą ćwiczę i która ma ww metody

edytowany 1x, ostatnio: Krajeski
Patryk27
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
1

W takim wypadku teraz tamtą funkcję musisz zrobić async i napisać await egz.getData() - i tak dalej, i tak dalej.

Innego wyjścia (oprócz wykorzystywania .then(), ofc.) nie ma - once you go async, you never go back.


edytowany 1x, ostatnio: Patryk27
KR
  • Rejestracja:ponad 6 lat
  • Ostatnio:około rok
  • Postów:83
0

Żebym się nie pogubił - zatem na samej 'górze'

Kopiuj
window.onload = async function() {myFunction()};

async function myFunction() {

  const egz = new ListModel; await console.log(egz.getData())
  
  }

a w klasie

Kopiuj
async remoteLoad(){
var that = this;
var result = null;
    try {
        const x = await fetch('https://api.myjson.com/bins/amapk');
        const resp = await x.json();
        console.log (resp);
        
        return resp;

        }

        catch(e){console.log(e)}
   
}


async getData() {
    return this.storageService.areInStorage() ? this.storageService.load('localBooks') : await this.remoteLoad();
}
KR
Jeżeli tak, to nadal zwraca promise. Mi już nie zalezy na eleganckim rozwiązaniu ale by działało
Patryk27
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
0
Kopiuj
window.onload = function () {
  myFunction()
};

Event handler nie musi być async (chyba że planujesz w nim robić await), reszta wygląda ok.


KR
bez zmiany - wywala promise
Patryk27
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
0

W którym miejscu? + pokaż cały kod


edytowany 1x, ostatnio: Patryk27
KR
  • Rejestracja:ponad 6 lat
  • Ostatnio:około rok
  • Postów:83
0

Wywaliłem wszystko co by zamącało

Kopiuj
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="./modernizr-custom.js"></script>
    
    <title>Document</title>
</head>
<body>

<script src= './script.js'></script>
</body>
</html>
Kopiuj
window.onload = function() {myFunction()};

async function myFunction(location) {
const egz = new ListModel; await console.log(egz.getData())
 
  }

class EventEmitter {
    constructor() {
      this._events = {};
    }
  
    on(evt, listener) {
      (this._events[evt] || (this._events[evt] = [])).push(listener);
      return this;
    }
  
    emit(evt, arg) {
      (this._events[evt] || []).slice().forEach(lsn => lsn(arg));
    }
  }
 
class ListModel extends EventEmitter {
    constructor(items) {
      super();
      
      this.sessionStorage = Modernizr.sessionstorage;
      this.temp= null;
      
      
        
    }


async remoteLoad(){

    try {
        const x = await fetch('https://api.myjson.com/bins/amapk');
        const resp = await x.json();
        console.log (resp);
        
        return resp;

        }

        catch(e){console.log(e)}
   
}

async getData() {
    return  await this.remoteLoad();
}

}
   
Patryk27
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
1
Kopiuj
await console.log(egz.getData())

vs

Kopiuj
console.log(await egz.getData())

Już drugi raz podałem Ci wprost to, co musisz napisać, i drugi raz zrobiłeś to źle ;-p


edytowany 2x, ostatnio: Patryk27
KR
  • Rejestracja:ponad 6 lat
  • Ostatnio:około rok
  • Postów:83
0

Działa !!!!
Pytanie jak z tym dalej. Czy każde wywołanie metody modelu będę musiał poprzedzać await -em? Czy jeżeli je będę definiował - bo na razie to golizna - to też wszedzie await?

siloam
Przecież Ci Patryk napisał: once you go async, you never go back. Albo callback hell, albo promises albo await. Najbardziej eleganckie jest await chociaż obietnice też są ok. Nie bój się ich. Nie ugryzą.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.