Javascript progress update during script execution
Hello everyone,
I'm using the js
object to manipulate a large SQLite database of sound files. When updating the records of the database (which can take some time), I am trying to use post
to issue messages to the console to track the progress.
The problem is that the messages are only posted to the console when the execution of the JS script is done. It's the same with the outputs (see the example, the bangs are issued at the end of the execution of the script).
The same happens with Tasks. They're only started when the script has finished executing.
Any ideas on getting an update synchronously?
(To run the example, save the javascript code below in pause.js
)
outlets = 2;
function bang() {
var tsk = new Task(ticker, this);
tsk.interval = 400;
tsk.repeat(10);
for (var i = 0; i < 10; i++){
const startTime = new Date().getTime();
var currentTime = null;
do {
currentTime = new Date().getTime();
} while (currentTime - startTime < 500);
post(i);
outlet(1, "bang");
}
}
function ticker() {
post("tick")
outlet(0, "bang");
}
Continuing on the experiments, I've now established that the tasks aren't asynchronous. A task only repeats after it's done. In the example below, you can see that each of the repetitions takes 1200ms to happen, even though the repeat interval is only 700ms.
function bang() {
var tsk = new Task(ticker, this);
tsk.interval = 700;
tsk.repeat(10);
}
function ticker() {
const startTime = new Date().getTime();
var currentTime = null;
do {
currentTime = new Date().getTime();
} while (currentTime - startTime < 500);
post("tick");
outlet(0, "bang");
}
I'm unclear about what your do/while and looping constructs are trying to accomplish. This should be all you need...
function bang() {
var tsk = new Task(ticker2, this);
tsk.interval = 700;
tsk.repeat(10);
}
function ticker2() {
post( parseInt( this.max.time ), "\n" );
post("tick")
outlet(0, "bang");
}
edit: Nevermind, I now get that your do/while delaying construct is I guess just a pseudo code to simulate work being done.
Answering my own question - It looks like to get asynchronous execution and the sort of progress tracking I'm looking for, Node for Max is the way forward.
But any ideas or workarounds are still welcome!
SQLite is blocking the main thread and creating way to much symbols in JS. So yes, NodeJS or C to do it asyncronous..
Also the build-in SQLite version is out of date. (haven't checked the version in Max 8.6, but I guess it hasn't been changed)
I have some experience in this from making my own version of tasks for Scheme for Max with the underlying Max primitives ("clocks" in the SDK).
You are correct, tasks are not asynchronous. There is only one JS thread (the lower priority main or UI thread), and only one task can run at a time. However, one can make many of them if you want many independent timers. While you may eventually hit some memory allocation performance issues, it takes creating many thousands for this to happen.
If you want ansynchronous, you will need Node for Max (or similar). But remember then everything is async. To manipulate a large database I would say you want a combination of local js code (running in the max thread) and node4max code (which essentially acts like a remote server). You could have node for max message back to your local code occasionally and post to the console. Under the hood that is what n4m is doing all the time, there is just a layer that hides the messaging from users. It's all json communication between the node process and the local code in the node max object.
Thanks a lot for the answers, node4max it is 😎