Newbie: Problem TypeScript with Promise

Ich versuche seit Wochen Promise innerhalb class einzubauen und Kombination soll auch stimmen. Ich wäre Hilfe sehr dankbar.

import {element, by, ElementFinder} from 'protractor';

export class YearMonthDayHoursMinutesSeconds {
	public ymdhms_timestamp_year: ElementFinder;
	public ymdhms_timestamp_month: ElementFinder;
	public ymdhms_timestamp_day: ElementFinder;
	public ymdhms_timestamp_hours: ElementFinder;
	public ymdhms_timestamp_minutes: ElementFinder;
	public ymdhms_timestamp_seconds: ElementFinder;
	public ymdhms_timestamp_button: ElementFinder;
	
	public request_ymdhms_timestamp_year: ElementFinder;
	public request_ymdhms_timestamp_month: ElementFinder;
	public request_ymdhms_timestamp_day: ElementFinder;
	public request_ymdhms_timestamp_hours: ElementFinder;
	public request_ymdhms_timestamp_minutes: ElementFinder;

	constructor() {
		this.ymdhms_timestamp_year = element(by.id("hf-d1")).element(by.className("dateform year")),
		this.ymdhms_timestamp_month = element(by.id("hf-d2")).element(by.className("dateform month")),
		this.ymdhms_timestamp_day = element(by.id("hf-d3")).element(by.className("dateform day")),
		this.ymdhms_timestamp_hours = element(by.name("hh")),
		this.ymdhms_timestamp_minutes = element(by.name("mn")),
		this.ymdhms_timestamp_seconds = element(by.name("ss")),
		this.ymdhms_timestamp_button = element.all(by.buttonText("Human date to Timestamp")).first()		
	}
	
	public testrequest(year: string, month: string, day: string, hours_utc: string, minutes: string, seconds: string) {
		expect(this.request_ymdhms_timestamp_year).toEqual("" + (year));
		expect(this.request_ymdhms_timestamp_month).toEqual("" + (month));
		expect(this.request_ymdhms_timestamp_day).toEqual("" + (day));
		expect(this.request_ymdhms_timestamp_hours).toEqual("" + (hours_utc));
		expect(this.request_ymdhms_timestamp_minutes).toEqual("" + minutes);
	}

	public async perform(year: string, month: string, day: string, hours: string, minutes: string, seconds: string) {
		await this.ymdhms_timestamp_year.clear();
		await this.ymdhms_timestamp_year.sendKeys(year);
		await this.ymdhms_timestamp_month.clear();
		await this.ymdhms_timestamp_month.sendKeys(month);
		await this.ymdhms_timestamp_day.clear();
		await this.ymdhms_timestamp_day.sendKeys(day);
		await this.ymdhms_timestamp_hours.clear();
		await this.ymdhms_timestamp_hours.sendKeys(hours);
		await this.ymdhms_timestamp_minutes.clear();
		await this.ymdhms_timestamp_minutes.sendKeys(minutes);
		await this.ymdhms_timestamp_seconds.clear();
		await this.ymdhms_timestamp_seconds.sendKeys(seconds);
		await this.ymdhms_timestamp_button.click();
	}
	//public async ConvertedValue: Promise<string>{}
/*
	public CoP: number = 1;
	let PromiseTest = new Promise((resolve, reject) => {
		setTimeout(function() {
			resolve(this.CoP);
		}, 1000);
	});
	PromiseTest.then((val) => {
		console.log('Done!');
	}).catch((reason) => {
		console.log('Error ('+reason+') here.');
	});
*/
}
  1. Tach!

    Ich versuche seit Wochen Promise innerhalb class einzubauen und Kombination soll auch stimmen. Ich wäre Hilfe sehr dankbar.

    Ja, aber beschreib dazu bitte das Problem.

    dedlfix.

    1. Ziel ist, dass obige Befehle nicht in der Reihenfolge ausgeführt wird, deshalb mit Hilfe Promise in Reihenfolge ausführen.

      Problem ist, dass ich Promise nicht ganz verstanden habe, wie man es programmieren soll. Programmieren habe ich es schon siehe unteres Teil, aber es ist immer noch außerhalb Class und Promise liest obige Befehle nicht aus.

      1. Tach!

        Ziel ist, dass obige Befehle nicht in der Reihenfolge ausgeführt wird, deshalb mit Hilfe Promise in Reihenfolge ausführen.

        Ich hoffe, dass ich den eigentlichen Sinn hinter dem verworrenen Satz verstanden habe.

        Jedenfalls ist async-await nichts anderes als Promises in anderer Syntax. Wenn das Ziel nicht damit erreichbar ist, hilft es auch nicht, noch mehr Promises draufzuwerfen. Sinnvoll wäre eine Ursachenermittlung. Wird denn vielleicht das Promise eher resolved als die eigentliche Funktion ausgeführt wird? Dann wäre das ein Problem mit dem Protractor, und es wäre sinnvoll, zu ergründen ob der Protractor eine andere Vorgehensweise bietet, so dass das Promise erst nach der Arbeit als erledigt gemeldet wird und nicht schon, wenn er die Aufgabe erfolgreich in eine Job-Queue eingestellt hat. Aber dazu kann ich nichts weiter sagen, das ist nur eine Vermutung, weil ich den Protractor nicht weiter kenne.

        Problem ist, dass ich Promise nicht ganz verstanden habe, wie man es programmieren soll.

        Meine Erfahrung sagt, dass es in solch einem Fall besser ist, erstmal das Problem zur Seite zu legen und sich der unbekannten Technik unvoreingenommen zu nähern, anstatt zu versuchen, in der Technik eine Lösung für das eigentliche Problem zu entdecken. Wenn man nun weiß, wozu Promises gut sind und wie man sie verwendet, kann man besser einschätzen, ob sie sich Lösung für das eigentliche Problem eignen. - Im Falle der Promises ist das Lernen auch keine verschwendete Zeit, denn das ist eine Technik, die einem heutzutage recht häufig begegnet.

        dedlfix.

      2. Hallo Newbie,

        ich bin in Typescript, Angular und Protractor nicht wirklich geübt.

        Aber: die Methoden clear() und sendKeys() des ElementFinder liefern Dir ein Promise zurück. Auf dieses Promise solltest Du warten, bis es resolved ist, damit die Folgeaktionen Sinn ergeben.

        Genau das tust Du bereits mit dem await. Das ist der Typescript-Weg um zu sagen: Da kommt ein Promise, warte darauf und mach dann weiter. Dein Code sollte ausreichen, um die diversen .clear() und .sendKeys() Aufrufe strikt nacheinander aufzurufen.

        Dadurch, dass deine perform-Methode ihrerseits async ist, gibt sie ebenfalls ein Promise zurück. Das heißt:

        obj.perform();
        obj.testrequest(2019, 06, 11, 13, 14, 15);
        

        funktioniert so nicht, weil perform sofort zurückkehrt. Die clear() und sendKeys() Aufrufe sind nocht nicht fertig.

        Das hier sollte besser funktionieren:

        await obj.perform();
        obj.testrequest(2019, 06, 11, 13, 14, 15);
        

        Das muss wiederum in einer async-Funktion stehen, damit es funktioniert.

        Das von Dir programmierte Beispielpromise tut jedenfalls nicht viel; es wartet eine Sekunde und gibt dann this.CoP zurück. In reinem JavaScript wäre das ein Fehler, weil in einer Callback-Funktion this eine andere Bedeutung bekommt. Aber es ist Typescript und der Transpiler könnte das anders sehen.

        Ein Hinweis noch zu deinen Lokatoren:

        element(by.id("hf-d1")).element(by.className("dateform year"))
        

        Das soll doch sicherlich bedeuten: Finde das Element mit id hf-d1 und suche darin ein Element mit dem class-String "dateform year". Zum einen kann man das sinnvoller kombinieren, zum anderen ist eine Suche nach className sehr fragil. Das class-Attribut kann mehrere Klassen auflisten, und man kann da "dateform year" genauso schreiben wie "year dateform". Du wärest hier mit dem css Lokator besser bedient, der einen CSS Selector akzeptiert:

        element(by.css("#hf-d1 .dateform.year"))
        

        Damit bist Du von der konkreten Reihenfolge im class-Attribut unabhängig, und es können auch noch weitere Klassen oder Leerzeichen im Attribut stehen, ohne dass deine Suche kaputtgeht.

        Rolf

        --
        sumpsi - posui - clusi
        1. Tach!

          Das von Dir programmierte Beispielpromise tut jedenfalls nicht viel; es wartet eine Sekunde und gibt dann this.CoP zurück. In reinem JavaScript wäre das ein Fehler, weil in einer Callback-Funktion this eine andere Bedeutung bekommt. Aber es ist Typescript und der Transpiler könnte das anders sehen.

          Auch in modernem Javascript gibt es die Arrow Function Syntax.

          var functionReference = () => {...};
          

          statt

          var functionReference = function() {...};
          

          Wenn diese verwendet wird, wird kein neues this erzeugt, sondern das vorhandene this des äußeren Scopes verwendet. Auch Typescript transpiliert das nur auf diese Weise für älteres Javascript, wenn die Arrow-Syntax verwendet wird.

          Nach meiner Erfahrung hatte ich noch keinen Grund, gerade mit Typescript die herkömmliche statt der Arrow-Syntax zu verwenden, und sich so das this-Problem aufzuhalsen.

          dedlfix.

          1. Hallo dedlfix,

            du willst also sagen: wenn ich mit einer anonymen inline function arbeite, habe ich auch unter Typescript das this-Problem. Danke.

            Ich fürchte nur, wir diskutieren hier 3km über dem Kopf des OP...

            Rolf

            --
            sumpsi - posui - clusi
            1. Tach!

              du willst also sagen: wenn ich mit einer anonymen inline function arbeite, habe ich auch unter Typescript das this-Problem. Danke.

              Typescript macht die Dinge nicht anders, nur besser.

              Ich fürchte nur, wir diskutieren hier 3km über dem Kopf des OP...

              Das sollte man aber wissen, das ist essentiell.

              dedlfix.