Jint: async/await und Callback-Unterstützung

Erstellt am 18. Juni 2018  ·  10Kommentare  ·  Quelle: sebastienros/jint

Ich war überrascht, keine Probleme oder Pull-Anforderungen zur Unterstützung von C#/JS async/await und Task-Unterstützung zu finden.

In einer perfekten Welt könnte ich das transparent machen und die aufrufende Methode "anhalten" (wie #192) oder einen Rückrufmechanismus verwenden (was Skripte jedoch viel komplexer machen würde).

Ich würde es vorziehen, return task.Result und Freunde zu vermeiden, damit ich nicht irgendwann in eine Sackgasse komme.

Hat irgendjemand vor der weiteren Untersuchung tatsächlich versucht, Unterstützung in Jint zu asynchronisieren/abzuwarten? @sebastienros ist das etwas, das Sie unterstützen möchten, z. B. durch das native ECMA-262 async/await (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) ? Irgendein fehlgeschlagener oder teilweiser Versuch?

Um Verwirrung zu vermeiden, geben Sie diesen C#-Code ein:

public async Task<string> loadSomething(string path) {
  return await File.ReadAllTextAsync(path);
}

Ich würde jedes dieser JavaScript-Äquivalente für richtig halten (in der Reihenfolge der Präferenz):

// Pausing (easiest for script writers):
var x = loadSomething('test.txt');
// Async Function (concise)
var x = await loadSomething('test.txt');
// Promises (well known)
var x;
loadSomething('test.txt').then(function(result) { x = result });;
// Callbacks (worst case)
var x;
loadSomething('test.txt', function(result) { x = result });;

Ideen oder Feedback dazu sind willkommen; Ich möchte es vermeiden, Zeit damit zu verbringen, wenn es nicht zusammengeführt würde oder wenn der Aufwand für das, was ich mir leisten kann, zu groß ist.

es6

Hilfreichster Kommentar

Promise-Unterstützung wurde implementiert, aber noch keine Unterstützung für async/await-Schlüsselwörter.

Alle 10 Kommentare

Können Sie mit Folgendem nicht einen einfachen Rückruf in ein Versprechen umwandeln?

```c#
öffentliche Klasse AsyncService {
public void LoadAsync (JValue-Eingabe, dann JValue, JValue fehlgeschlagen) {
Task.Run (async () => {
Versuchen {
var result = await ..... asynchrone Verarbeitung in C#
then.Invoke( null, result );
} catch(Ausnahme Bsp.) {
failed.Invoke(null, ex.ToString());
}
});
}
}

```TypeScript

             loadAsync( input ) : Promise<any> {
                  return new Promise((resolve,reject) => {
                           asyncService.loadAsync( input, resolve, reject);
                  });
             }


     // now you can use loadAsync method with async await

@ackava Danke, dass du deine Ideen geteilt hast. Es sieht so aus, als würden Sie TypeScript verwenden, was erklären würde, warum die Verwendung des Promise -Konstruktors, der => -Syntax und schließlich die Verwendung await für Sie funktionieren würde :) Die Verwendung eines Transpilers ist eine Idee, die es wert ist, untersucht zu werden.

Mir ist klar, dass die Unterstützung von async/await ziemlich genau ES2017 unterstützen würde, das ein eigenes offenes Problem hat: https://github.com/sebastienros/jint/issues/343 - das würde wahrscheinlich (ich kann nur raten) mein Problem lösen, je nachdem, wie @sebastienros entschieden hat, „await“ für C#-unterstützte Funktionen zu implementieren. Im Moment sieht es so aus, als wäre der Promise -Konstruktor nicht im 3.0 -Zweig implementiert, also müssen wir wohl abwarten. Wenn ich mehr Zeit hätte, würde ich versuchen, dies in Jint beizusteuern, aber ich glaube nicht, dass ich für einige Zeit die Führung übernehmen kann.

Wenn sich jemand fragt, wie man in Jint transpiliert: https://github.com/sebastienros/jint/issues/274 (noch nicht ausprobiert)

Hallo zusammen, ich wiederhole @christianrondeau in dem Wunsch nach async/await-Unterstützung.

Während Promises funktionieren würden, wäre es noch einfacher, wenn die Engine einfach auf einen Funktionsdelegaten "warten" könnte, der an "SetValue" übergeben wird - wenn dieser Delegate eine asynchrone Methode umschließt.

Angenommen, wir hätten den folgenden C#-Code:

Engine engine = new Engine(cfg => cfg.AllowClr());
Func<string, Task<string>> thisFunc = DoOperation;
engine.SetValue("DoOperation", thisFunc);

//C# method of DoOperation
public async Task<string> DoOperation(string input)
{
   //assume that SomeAsynchronousOperation returns a string...

   return await SomeAsynchronousOperation();
}

Das ideale Szenario wäre dann für eine "ExecuteAsync"-Methode auf der Engine wie:

engine.ExecuteAsync("DoOperation('my_input');");

... wo intern die Engine den Funktionsdelegierten zum Zeitpunkt des Aufrufs "erwarten" würde.

@sebastienros , ist das überhaupt möglich? Wenn nicht, gibt es andere Problemumgehungen, die Sie vorschlagen könnten?

Jint ist eine phänomenale Software, obwohl ich es in meinem speziellen Fall mit starker Netzwerk-E/A zu tun habe. Daher ist die async/await-Unterstützung von entscheidender Bedeutung.

Hat jemand irgendwelche Fortschritte zu diesem Thema gemacht, die es wert sind, geteilt zu werden? Ich bin in einer Situation, in der ich einige asynchrone Methoden aufrufen muss.

Hallo,
Ich habe vielleicht eine Lösung für Sie, es verwendet keine await-Syntax, aber Sie können then(...) verwenden:

C#-Funktion zum Aufrufen von JS:

public static Promise<bool> alert(string msg)
        {
            return new Promise<bool>(Task.Run<Task<bool>>(new Func<Task<bool>>(async() => { 

                bool isFinished = false;
                Device.BeginInvokeOnMainThread(async () =>
                {
                    await App.Current.MainPage.DisplayAlert("Message", msg, "Ok");
                    isFinished = true;
                });
                while (!isFinished) await Task.Delay(10);
                return true;
            })));
        }

C#-Klasse „Versprechen“ :

public class Promise<T>
    {
        Task<T> tache;
        public Promise(Task<T> tache)
        {
            this.tache = tache;
        }
        public Promise(Task<Task<T>> tache)
        {
            this.tache = tache.Result;

        }
        public void then(Action<T> onfinish)
        {
            this.tache.ContinueWith(rep =>
            {
                onfinish.Invoke(rep.Result);
            });
        }

    }

Javascript-Code:

var repAlert=alert("valeur interne = "+valeur);
    repAlert.then(function(rep){
        console.log("journal ok rep="+rep); // return Boolean value (true)
    });
    console.log("journal ok repAlert="+repAlert); // Return Promise object

Die catch-Funktion ist nicht implementiert, aber Sie können mit diesem Beispiel auskommen ...

Dieser Code ist Teil eines Xamarin-Projekts

Stoßen Sie dieses für eine Frage an: Da Jint ein Interpreter ist, gibt es Gründe dafür, dass C#-Methoden nicht asynchron sein/Task zurückgeben können, sondern synchron zum Benutzerskript aussehen?

Ich habe einen Fall mit sehr vielen kleinen einfachen Skripten, die asynchrone Methoden aufrufen sollten. Ich möchte die Komplexität der Einführung von await/Promise-Objekten in die Benutzerskripte vermeiden, da keines der Skripte Parallelität aufweist, die tatsächlichen asynchronen Code erfordert.

Sie wollen also in der Lage sein, await zu tun? Aber mach das automatisch.
Einer der Zwecke der Task-API besteht schließlich darin, dass Sie Dinge im Hintergrund ausführen können.

Sie wollen also in der Lage sein, await zu tun? Aber mach das automatisch.
Einer der Zwecke der Task-API besteht schließlich darin, dass Sie Dinge im Hintergrund ausführen können.

Ja, aber die Benutzerskripte in meinem Fall brauchen es nicht wirklich. Dennoch benötigt der Hostprozess es, um das Blockieren des Threads zu vermeiden.

Dies könnte tatsächlich eine gute Idee sein, dies zu unterstützen, sodass die API nicht asynchron auf das Skript basiert, sondern für die Verwendung asynchron ist.

Promise-Unterstützung wurde implementiert, aber noch keine Unterstützung für async/await-Schlüsselwörter.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen