NEWS
[gelöst] Warten auf Erstellen und Befüllen von DP
-
Ich habe ein Problem bei der Weiterbearbeitung von Daten...
Ich lese 2 JSON aus und erstelle / befülle daraus jeweils in einer Funktion die Datenpunkte.
Da der Vorgang unterschiedlich lang dauert, kommt es jetzt vor das die 3. Funktion auf Daten zugreifen will, die noch nicht geschrieben sind.
Wie muss ich meinen Aufruf gestalten, damit er erst ausgeführt wird, wenn der Schreibvorgang abgeschlossen ist?
Mein Versuch...async function asyncCall() { try { await DatenAuswerten(basicArray, basicBasisOrdner); await DatenAuswerten(currentArray, currentBasisOrdner); await DatumAnpassen(basicArray, basicBasisOrdner); } catch (e) { console.log('Fehler'); } }
-
@dirk_1930 sind die anderen Methoden auch async definiert ?
-
@arteck
Hmm - nö
Nutze zum ersten mal den async Aufruf...
Muss ich bei den aufgerufenen Funktionen async davor setzten? Ich füge mal das aktuelle Script mit an...
console.log("====== Skript gestartet ======"); // **** Json & Array initialisieren *** const currentJson = '0_userdata.0.meteoblue.json.meteoblue_current_json'; const currentArray = JSON.parse(getState(currentJson).val); const currentBasisOrdner = "0_userdata.0.meteoblue.current"; const basicJson = '0_userdata.0.meteoblue.json.meteoblue_basicday_json'; const basicArray = JSON.parse(getState(basicJson).val); const basicBasisOrdner = '0_userdata.0.meteoblue.basic-day' asyncCall(); async function asyncCall() { try { await DatenAuswerten(basicArray, basicBasisOrdner); await DatenAuswerten(currentArray, currentBasisOrdner); await DatumAnpassen(basicArray, basicBasisOrdner); } catch (e) { console.log('Fehler beim Aufruf'); } } async function DatenAuswerten(array, ordner) { console.log('function DatenAuswerten'); for (var key of Object.keys(array)) { DatenpunktErstellen(array, key, key, ordner); } } async function DatenpunktErstellen(array, key, fullKeyName, ordner) { var basisOrdner = ordner; for (var key2 of Object.keys(array[key])) { var fullKeyName2 = fullKeyName + "." + key2; var value = array[key][key2]; if (Array.isArray(value)) { // Array.isArray(obj) - Wenn der Wert ein Array ist wird true zurückgegeben ===> Es gibt eine 2. Ebene for (var i = 0; i <= (value.length) - 1; i++) { var arrayItemKey = basisOrdner + "." + fullKeyName + ".data_" + i + "." + key2; if (!existsState(arrayItemKey)) { // Wenn der Datenpunkt nicht vorhanden ist - anlegen createState(arrayItemKey, value[i], async function () { }); } else { setState(arrayItemKey, value[i], true); } } } else { var itemKey = currentBasisOrdner + "." + fullKeyName2; if (!existsState(itemKey)) { // Wenn der Datenpunkt nicht vorhanden ist - anlegen createState(itemKey, value, async function () { }); } else { setState(itemKey, value, true); } } } } async function DatumAnpassen(array, basicBasisOrdner) { console.log('function DatumAnpassen'); let zaehler = 0; let time = (array.data_day.time); // Time aus Array for (let key in time) { let subOrdner = '.data_day.data_' + zaehler; let dataPoint = basicBasisOrdner + subOrdner + '.time'; //Ordner Zeit auslesen als Trigger für Farbe let datum = getState(dataPoint).val; console.log(datum); let tag = formatDate(datum, "W"); // Datum Formatieren https://github.com/ioBroker/ioBroker.javascript/blob/master/docs/en/javascript.md#formatdate let ordnerTagNeu = basicBasisOrdner + subOrdner + ".tag"; if (!existsState(ordnerTagNeu)) { createState(ordnerTagNeu, tag, async function () { }); } else { setState(ordnerTagNeu, tag, true); } let datumKurz = formatDate(datum, "DD.MM"); // Datum Formatieren https://github.com/ioBroker/ioBroker.javascript/blob/master/docs/en/javascript.md#formatdate let ordnerDatumKurz = basicBasisOrdner + subOrdner + ".datum"; if (!existsState(ordnerDatumKurz)) { createState(ordnerDatumKurz, datumKurz, async function () { }); } else { setState(ordnerDatumKurz, datumKurz, true); //Datenpunkt setzten } zaehler++; } }
-
@dirk_1930
Mindestens müsstest du die asynchronen Varianten von createState und setState verwenden. Eine leere Callback-Funktion sorgt nicht dafür, dass gewartet wird, egal ob diese async ist oder nicht.createState(ordnerDatumKurz, datumKurz, async function () { });
müsste also
await createStateAsync(ordnerDatumKurz, datumKurz);
lauten und
setState(ordnerDatumKurz, datumKurz, true);
stattdessen
await setStateAsync(ordnerDatumKurz, datumKurz, true);
Grundsätzlich macht es keinen Sinn, eine Funktion als
async
zu deklarieren, wenn du darin keinawait
verwendest.Es ist genau anders herum: Das
await
ist das, was wartet, wenn die aufgerufene Funktionasync
ist bzw. einen Promise zurück gibt. Umawait
zu nutzen, muss die enthaltende Funktionasync
sein.
Diese kann dann wiederum mitawait
aufgerufen werden, dazu muss die aufrufende Funktionasync
sein, etc...Das zieht sich komplett durch.
-
@alcalzone
... das klingt mega kompliziert. Für mich als Javascript Anfänger völlig verwirrendIch habe Deine Vorschläge jetzt umgesetzt, allerdings ruft die Funktion DatumAnpassen immer noch einen DP auf, der zu dem Zeitpunkt noch nicht existiert.
An welcher Stelle müsste ich jetzt noch etwas ändern?
console.log("====== Skript gestartet ======"); // **** Json & Array initialisieren *** const currentJson = '0_userdata.0.meteoblue.json.meteoblue_current_json'; const currentArray = JSON.parse(getState(currentJson).val); const currentBasisOrdner = "0_userdata.0.meteoblue.current"; const basicJson = '0_userdata.0.meteoblue.json.meteoblue_basicday_json'; const basicArray = JSON.parse(getState(basicJson).val); const basicBasisOrdner = '0_userdata.0.meteoblue.basic-day' asyncCall(); async function asyncCall() { try { await DatenAuswerten(basicArray, basicBasisOrdner); await DatenAuswerten(currentArray, currentBasisOrdner); await DatumAnpassen(basicArray, basicBasisOrdner); } catch (e) { console.log('Fehler beim Aufruf'); } } function DatenAuswerten(array, ordner) { console.log('function DatenAuswerten'); for (var key of Object.keys(array)) { DatenpunktErstellen(array, key, key, ordner); } } async function DatenpunktErstellen(array, key, fullKeyName, ordner) { var basisOrdner = ordner; for (var key2 of Object.keys(array[key])) { var fullKeyName2 = fullKeyName + "." + key2; var value = array[key][key2]; if (Array.isArray(value)) { // Array.isArray(obj) - Wenn der Wert ein Array ist wird true zurückgegeben ===> Es gibt eine 2. Ebene for (var i = 0; i <= (value.length) - 1; i++) { var arrayItemKey = basisOrdner + "." + fullKeyName + ".data_" + i + "." + key2; if (!existsState(arrayItemKey)) { // Wenn der Datenpunkt nicht vorhanden ist - anlegen await createStateAsync(arrayItemKey, value[i]); } else { await setStateAsync(arrayItemKey, value[i], true); } } } else { var itemKey = currentBasisOrdner + "." + fullKeyName2; if (!existsState(itemKey)) { // Wenn der Datenpunkt nicht vorhanden ist - anlegen await createStateAsync(itemKey, value); } else { await setStateAsync(itemKey, value, true); } } } } async function DatumAnpassen(array, basicBasisOrdner) { console.log('function DatumAnpassen'); let zaehler = 0; let time = (array.data_day.time); for (let key in time) { let subOrdner = '.data_day.data_' + zaehler; let dataPoint = basicBasisOrdner + subOrdner + '.time'; //Ordner Zeit auslesen als Trigger für Farbe let datum = getState(dataPoint).val; let tag = formatDate(datum, "W"); // Datum Formatieren https://github.com/ioBroker/ioBroker.javascript/blob/master/docs/en/javascript.md#formatdate let ordnerTagNeu = basicBasisOrdner + subOrdner + ".tag"; if (!existsState(ordnerTagNeu)) { await createStateAsync(ordnerTagNeu, tag); } else { await setStateAsync(ordnerTagNeu, tag, true); } let datumKurz = formatDate(datum, "DD.MM."); // Datum Formatieren https://github.com/ioBroker/ioBroker.javascript/blob/master/docs/en/javascript.md#formatdate let ordnerDatumKurz = basicBasisOrdner + subOrdner + ".datum"; if (!existsState(ordnerDatumKurz)) { await createStateAsync(ordnerDatumKurz, datumKurz); } else { await setStateAsync(ordnerDatumKurz, datumKurz, true); } zaehler++; } }
-
@dirk_1930 sagte in Warten auf Erstellen und Befüllen von DP:
An welcher Stelle müsste ich jetzt noch etwas ändern?
Hier ist die async-await-Kette unterbrochen:
function DatenAuswerten(array, ordner) { console.log('function DatenAuswerten'); for (var key of Object.keys(array)) { DatenpunktErstellen(array, key, key, ordner); } }
Da fehlt ein async vor dem function und ein await for dem DatenpunktErstellen.
-
Vielen, vielen Dank! Es geht!