Ich schreibe ein Applescript für Spotify, das zwei Dinge tun soll:
- Protokolliere jedes neu gespielte Lied.
- Überprüfen Sie alle N Sekunden, welches Audiogerät verwendet wird.
Ich mache (1) durch eine einfache Schleife, die prüft, wie viel von der Spur übrig bleibt, und verwende diesen Wert dann in einer Verzögerungsanweisung in der Schleife (nicht erforderlich, um die Schleife mit voller Geschwindigkeit auszuführen). N ist jedoch normalerweise viel niedriger als die verbleibende Zeit der aktuellen Spur. Daher möchte ich, dass Aufgabe (2) in einer separaten Schleife mit N-0,5 als Verzögerungswert ausgeführt wird. Grundsätzlich möchte ich Schleifen gleichzeitig mit demselben Skript ausführen. Ist das möglich?
(Natürlich könnte ich zwei separate Skripte verwenden, aber ich muss diese Lösung verteilen, wenn sie fertig ist. Daher ist eine geringere visuelle Komplexität - dh zwei Skripte, die gleichzeitig ausgeführt werden und Speicherplatz im Dock beanspruchen, gestartet werden müssen usw. - besser.)
Antworten:
Nicht einfach. Das Konzept von Prozessen und Threads ist in AppleScript nicht enthalten.
Sie benötigen ein anderes Tool für diesen Job. Swift ist vielleicht gut, es sei denn, Sie suchen nach Python oder etwas Etablierterem.
quelle
Sprachgrenzen
Ab macOS 10.13 unterstützt AppleScript Multithreading in einem einzelnen Skript nicht mehr. Die Verwendung
NSThread
in einem AppleScript scheint möglich zu sein , dies ist jedoch komplex und führt zu einer zweiten Einschränkung, der der Anwendung, mit der interagiert wird.Anwendungsgrenzen
Zusätzlich zu der AppleScript-Sprache selbst, die keine Threads nativ darstellt, ist es unwahrscheinlich, dass die aufgerufene Anwendung mit AppleEvents in einer Thread-optimalen Weise umgeht. AppleEvents werden von macOS in einer FIFO-Reihenfolge (First-In First-Out) zur Verarbeitung durch die Anwendung in die Warteschlange gestellt.
Die Anwendung kann Antworten auf lange laufende AppleEvents verschieben, dies erfordert jedoch zusätzliches Engineering, das nur wenige Anwendungen implementieren. Die meisten Anwendungen werden blockiert, bis das AppleEvent verarbeitet wird, bevor das nächste AppleEvent angezeigt wird.
Dies bedeutet, dass ein AppleScript mit mehreren Threads, das mit einer einzelnen Anwendung kommuniziert, wahrscheinlich nicht die erwarteten Leistungssteigerungen für den Aufwand sehen würde.
Einzelne Ereignisschleife?
Sie können sich dem Problem mit einer einzelnen Schleife nähern, die sich mit mehreren Ereignissen befasst. Die einzelne Schleife könnte N Sekunden lang schlafen, aufwachen und die anstehenden entsprechenden Aufgaben erledigen.
Die Antwort von Piyomaru zeigt einen Weg, einen ereignisbasierten Ansatz zu implementieren. Dieser Ansatz ist nicht multithreaded oder parallel. Es ist eine ereignisgesteuerte Schleife.
quelle
NSThread
bedeutet nicht, dass das Skript mit einem Thread versehen ist. Weitere Informationen finden Sie unter Gewindesicherheit .NSThread
. Kann es zum Threading geändert werden?AppleScript unterstützt jetzt Multithreading (macOS 10.10 oder höher). Und ursprünglich hat es seit 1993 eine Timer-Interrupt-Funktion (
on idle
Timer-Ereignishandler arbeitet gleichzeitig in einem einzelnen AppleScript).Ich habe einige AppleScripts mit iTunes geschrieben, wie Sie geschrieben haben. AppleScript kann Delegierte erstellen und Ereignisse anderer Anwendungen empfangen.
Dieses Beispiel-AppleScript kann die Änderung des Wiedergabestatus von iTunes empfangen. Sobald das Skript im Skript-Editor ausgeführt wird, empfängt es das Änderungsereignis von iTunes und zeigt den Namen des Titels im MacOS-Benachrichtigungsdialog an.
Der Punkt ist also, dass die Spotify-Anwendung eine solche Funktion wie iTunes bereitstellen kann oder nicht.
quelle
Ich würde vorschlagen, dies in JavaScript anstatt in AppleScript zu schreiben. JavaScript ist eine unterstützte Sprache für Apple Events Scripting. JavaScript ist Single-Threaded, aber es ist viel einfacher, nicht blockierenden asynchronen Code zu schreiben.
quelle