Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

07.01.2016, 17:13

[JavaScript] - Variabel in .then(function...

Hallöle,
ich versuche mich gerade an JavaScript und verstehe folgendes nicht.
Ich fülle ein Array und möchte dannach drauf zugreifen. Es funzt jedoch nicht ganz wie gedacht:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
function blub(URI){

var array = []

mopidy.library.lookup(URI).then(function(blabla){
array.push(blabla);
console.log(array[0]); // Ausgabe im Browser korrekt!
});

console.log(array); // Ausgabe im Browser = Array[ ]
console.log(array[0]); //Ausgabe im Browser = undefined

}


Greife ich noch in der Funktion drauf in der ich den Array fülle klappt alles. Ausserhalb bekomme ich nur dieses Array[ ]. Klicke ich jedoch im Browser debugger drauf werden meine Elemente gelistet.

Ich verstehe das nicht was mache ich Falsch?

MFG Urprimat
Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.

Linus Torvalds

2

07.01.2016, 17:24

Ich vermutete zuerst einen Fehler bei der closure der anonymen Funktion die du an .then() übergibst.
Könntest ja mal nach der array-instanzierung ein Object reinhacken, und als erstes in der anonymen funktion diesen Wert per console.log(...) ausgeben.

Da das aber auf den ersten Blick richtig aussieht könnte es auch das asynchrone Verhalten von .then() sein. Dann würdest du im log zuerst die beiden unteren console.log(...) Ausgaben sehen, und zuletzt das Ergebnis von dem console.log(...) innerhalb des .then().
Empires in Space
MMO 4X, Rundenbasiert
HTML5/TypeScript/Javascript/CSS/C#/SQL

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

07.01.2016, 18:08

Nur so 'ne spontane Idee, lookup(URI).then wird nicht zufällig asynchron später ausgeführt? Denn dann wäre klar, warum die untere Log-Ausgabe Fehler wirft, die würde nämlich zeitlich zuerst ausgeführt werden, bevor der Array überhaupt befüllt wurde.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Tobiking

1x Rätselkönig

  • Private Nachricht senden

4

07.01.2016, 18:37

Das then deutet darauf hin das die Funktion lookup ein Promise zurückgibt. Das heißt, so wie BlueCobold schon vermutet hat, wird die Funktion asynchron ausgeführt. Mit dem then kannst du einen Callback für den erfolgreichen Fall hinzufügen. Ein Promise bietet dir aber auch noch weitere Möglichkeiten wie Verkettung/Parallelausführung von Aktionen etc.

5

07.01.2016, 22:44

Tatsache!
Bin es mit Haltepunkten durchgegangen und das Array wird später gefüllt!
Ich versteh das nicht ganz...
Wie genau soll ich jt das Array füllen?

MFG
Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.

Linus Torvalds

xardias

Community-Fossil

Beiträge: 2 731

Wohnort: Santa Clara, CA

Beruf: Software Engineer

  • Private Nachricht senden

6

07.01.2016, 22:57

Der Grund ist ganz einfach. Es braucht Zeit bis das Array von der URL geladen wird, un du moechtest ja nicht den ganzen Browser aufhalten bis das fertig ist.

Stelle dir das ganze eher Eventbasiert vor, nicht als Programm welches von oben nach unten ablaeuft. Die Funktion in .then() wird ausgefuehrt sobald der Server geantwortet hat, d.h. saemtliche Logik die auf die Daten vom Server basieren sollte auch in dieser Funktion ausgefuehrt werden.

Wenn du damit Probleme hast wuerde es helfen wenn du genauer beschreibst was genau du machen moechtest.

7

08.01.2016, 10:16

Ok ich verstehe. Jedoch verstehe ich dann nicht, warum die erste Ausgabe, die noch in den {} der Function steht, korrekt ausgegeben wird?

Also, im grunde möchte ich einen Raspberry, auf dem ein Musikserver(Mopidy) läuft, ansprechen.
Die Funktion die ich gepostet habe untersucht (lookup) ein Element an der URI die übergeben wird. Zurück kommt ein Objekt(blabla) in dem die ID3tags der Musikdatei stehen. Diese sollen dann in den Array geschrieben werden damit sie im nächsten schritt einfacher in die Tabelle geschrieben werden können.

Davor hat es auch geklappt da ich die Daten direkt in die Tabelle geschrieben habe. Nun wollte ich jedoch die GetID3Tag() auslagern, da ich diese bestimmt für andere Zwecke benutzen werde.

Mfg Urprimat
Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.

Linus Torvalds

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

8

08.01.2016, 10:54

Vielleicht wird es verständlicher, wenn du den Code leicht umstrukturierst:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function blub(URI){
    
    var array = []
    function callback(blabla){
        array.push(blabla);
        console.log(array[0]); // Ausgabe im Browser korrekt!
    };
    
    mopidy.library.lookup(URI).then(callback);
    
    console.log(array); // Ausgabe im Browser = Array[ ]
    console.log(array[0]); //Ausgabe im Browser = undefined
    
}


Jetzt sollte ersichtlich sein: die Funktion mit dem Namen callback (vorher die anonyme Funktion die übergeben wurde) und ihr Inhalt wird erst ausgeführt, wenn sie aufgerufen wird. Wie schon geschrieben wurde, wird die übergebene Funktion nicht direkt ausgeführt, sondern erst, wenn die entsprechende Operation (der Lookup) fertig ist. Die Ausgabe innerhalb der Funktion funktioniert also, weil er nach der Anpassung des Arrays durchgeführt wird.
Da der Callback nur 1 Mal aufgerufen wird, dürfte es wohl ausreichend sein, wenn du innerhalb des Callbacks wiederum alles durchführst, was du mit deinem Array machen wolltest.
Weiterhin, zumindest mit dem bisherigen Code, brauchst du derzeitig kein Array, sondern würdest mit einer einfachen Variable auskommen. Wenn der weitere Code dann innerhalb des Callbacks liegt, muss diese auch nur innerhalb des Callbacks vorhanden sein (bspw. als der Parameter, den du bereits hast). Möglicherweise ist das aber auch erst der Anfang von dem, was du insgesamt machen wolltest, wo ein solches Array vielleicht doch erforderlich wäre...

(Das Auslagern und benennen der Funktion habe ich der Übersichtlichkeit wegen gemacht. Derzeitig ist es sinnvoller, direkt eine anonyme Funktion als Parameter zu übergeben.)
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Tobiking

1x Rätselkönig

  • Private Nachricht senden

9

08.01.2016, 10:58

Ok ich verstehe. Jedoch verstehe ich dann nicht, warum die erste Ausgabe, die noch in den {} der Function steht, korrekt ausgegeben wird?
...
Zurück kommt ein Objekt(blabla) in dem die ID3tags der Musikdatei stehen.

Das zeigt das du es noch nicht richtig verstanden hast. Es kommt kein Objekt zurück. Es wird eine Funktion aufgerufen und dieser Funktion das Objekt übergeben. Und dies geschieht dann wenn die Daten da sind. Es wird vielleicht deutlicher wenn man die Funktion explizit schreibt:

Quellcode

1
2
3
4
5
6
7
8
9
var array = [];

function HandleData(blabla) {
  array.push(blabla);
}

mopidy.library.lookup(URI).then(HandleData); // Ruft HandleData auf sobald Daten da sind

console.log(array); // Leer, da HandleData noch nicht aufgerufen wurde


Was du tun kannst ist etwas davon abhängig was du genau haben willst und welche Promise Implementierung verwendet wird. Ich vermute du willst mehr als eine URI abfragen und die Ergebnisse erst einmal sammeln bevor du sie anzeigst. Das einfachste wäre dafür die Promises mit all zu aggregieren.

Die grobe Idee wäre diese Richtung:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var array = [];

function HandleData(blabla) {
  array.push(blabla);
}

function CreateTable() {
  console.log(array);
}

var promiseArray = []

var promise = mopidy.library.lookup(URI).then(HandleData);
promiseArray.push(promise);

promise = mopidy.library.lookup(URI2).then(HandleData);
promiseArray.push(promise);

Promise.all(promiseArray).then(CreateTable);


Der Code kann fehlerhaft sein, aber soll eh nur die ungefähre Richtung zeigen.

10

14.01.2016, 22:27

Hallohallo,
Tut mir leid, dass ich mich jt erst melde.
Ich hatte etwas wening Zeit. Vielen Dank erstmal für die Antworten und ich werde es mir mal in ruhe ansehen.

MFG Urprimat
Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.

Linus Torvalds

Werbeanzeige