[TWC] How to delay the execution of a macro or a part of it

131 views
Skip to first unread message

whatever

unread,
Jun 22, 2017, 11:48:38 AM6/22/17
to TiddlyWiki
Hi!
I'm working on a plugin, which, depending on the amount of data it needs to process, can take up to a minute to render. In the mean time, the TWC is practically frozen. Is there any way to delay the processing of the macro until the tiddler is loaded? Or delay the processing part of the macro? Which would actually be preferable, if I could display a placeholder message that the macro is processing stuff. I've played with setTimeout, both inside and outside of the handler, but it didn't work. Any ideas?

w

whatever

unread,
Jun 30, 2017, 4:45:00 PM6/30/17
to TiddlyWiki
Bump.

Yakov

unread,
Jul 10, 2017, 3:47:08 PM7/10/17
to TiddlyWiki
Hello whatever,

could you specify what kind of computation does this macro require? Does it make any requests to external sources?

This may be of use: https://stackoverflow.com/questions/36588775/are-javascript-promise-asynchronous

Best regards,
Yakov.

PS you may be interested in joining the new TiddlyWikiClassic group: https://groups.google.com/forum/#!forum/tiddlywikiclassic

пятница, 30 июня 2017 г., 23:45:00 UTC+3 пользователь whatever написал:

whatever

unread,
Jul 10, 2017, 4:00:54 PM7/10/17
to TiddlyWiki
Hey, Yakov.
My plugin processes parameters from internal tiddlers, no external resources required. It's called InfoboxTablesPlugin [1] and I use it to generate Wikipedia-style infoboxes. The current version that's publicly available is not the latest though. The new version supports modules and includes, and I found that when the number of available parameters gets over a hundred, the wiki freezes until the plugin is done processing. Only then is the tiddler displayed. These are extreme test cases, of course, but the wiki is a bit slow even when there are fewer parameters to process.
I have seen the SO thread you posted, but I haven't had the time to play around yet.
I have also joined the TWC group.:D

[1] http://infoboxes.tiddlyspot.com/

w

Yakov

unread,
Jul 11, 2017, 2:39:14 PM7/11/17
to TiddlyWiki
Well, it sounds like Promises might help you. I'm not sure yet about the blocking nature of JS for interface, but what you can do is the following:

in handler, create a container and create a Promise to fill it – that Promise has to do the calculations;
chain another Promise to it, it has to grab the calculation results and build DOM.

What I think I understand is that the 2 promises will be fullfilled after the whole code, meaning after other wikifying, so the user will see other content. What I'm not sure at all is whether the first Promise will or will not block user interface (I don't know well why this blocking happens at all). Once the calculation is done, the second Promise will work and that one will certainly block user interface but at least it is not the long part, if I've understood you correctly.

I'm not familiar at all with Web Workers but looks like this is the second thing you should look into.

Best regards,
Yakov.

PS very interesting what you will come up with, I wonder if those tools can be used to make saving with TiddlyFox asynchronous (or more precisely, non-blocking), but I haven't learned enough stuff yet.

понедельник, 10 июля 2017 г., 23:00:54 UTC+3 пользователь whatever написал:

whatever

unread,
Jul 11, 2017, 2:59:02 PM7/11/17
to TiddlyWiki
Hey!
I think the issue is that JS is a single-thread language, if I understand correctly. I'm guessing that when you open the tiddler, the wikifier gets the content, queues all the macros inside it and only shows the tiddler once all macros have executed. I'll try playing around with Promises when I have the time, but my understanding is not all that good.
w

Yakov

unread,
Jul 14, 2017, 2:27:35 PM7/14/17
to TiddlyWiki
Hello whatever,

today I've read a very nice article about browsers' JS main loop and Web Workers [*] and it seems that Web Workers is exactly what you need. Like you said, JS is a single-thread, but Web Workers "break this rule": they are processed in separate threads and hence don't hang the interface. Still, they have their limitations: DOM can't be manipulated from a Web Worker. Hence, you should create a Web Worker and set an event handler: once the job is done by your Web Worker, you can change DOM. Normally WW are used with JS in a separate file, but this can be worked around using stuff like

var worker = new Worker( window.URL.createObjectURL( new BlobBuilder().append( "onmessage = function(e) { postMessage('hello habrahabr'); }" ).getBlob() ) ); worker.postMessage();

Another option is to use setTimeout instead of WW: in this trick JS bits (small enough) are executed between other stuff in the event loop and hence the interface doesn't hang [**].

Best regards,
Yakov.

[*] it's in Russian so probably not useful for you: https://habrahabr.ru/company/tradingview/blog/178261/
[**] see the first answer here: https://stackoverflow.com/questions/714942/how-to-stop-intense-javascript-loop-from-freezing-the-browser

вторник, 11 июля 2017 г., 21:59:02 UTC+3 пользователь whatever написал:
Reply all
Reply to author
Forward
0 new messages