Is asynchronous call of JavaScript function possible in Windows Script Host? - asynchronous

Imagine you have a simple function in Windows Script Host (JScript) environment:
function say(text) {
WScript.Sleep(5000);
WScript.Echo(text);
}
Is it possible to call say() asynchronously?
Note: Such browser-based methods as setInterval() or setTimeout are not available in WSH.

No, Windows Script Host doesn't support calling script functions asynchronously. You'll have to run two scripts simultaneously to achieve this effect:
// [main.js]
var oShell = new ActiveXObject("WScript.Shell");
oShell.Run(WScript.FullName + " say.js Hello");
WScript.Echo("Hello from main");
// [say.js]
WScript.Sleep(5000);
WScript.Echo(WScript.Arguments.Item(0));

As far as I know, there is no equivalent to setTimeout / setInterval under Windows Script Host (shockingly). However, you may find this simple function queue in another answer here on SO a useful starting point for emulating it. Basically what the guy did (his name is also "TJ", but it's not me) was create a function queue, and then you call its main loop as your main method. The main loop emulates the heartbeat in browser-based implementations. Quite clever, though I'd change the naming a bit.

Related

Single threaded asynchronous event loop with `winit`

I'm trying to build an NES emulator using winit, which entails building a game loop which should run exactly 60 times per second.
At first, I used std::thread to create a separate thread where the game loop would run and wait 16 milliseconds before running again. This worked quite well, until I tried to compile the program again targeting WebAssembly. I then found out that both winit::window::Window and winit::event_loop::EventLoopProxy are not Send when targeting Wasm, and that std::thread::spawn panics in Wasm.
After some struggle, I decided to try to do the same thing using task::spawn_local from one of the main asynchronous runtimes. Ultimately, I went with async_std.
I'm not used to asynchronous programming, so I'm not even sure if what I'm trying to do could work.
My idea is to do something like this:
use winit::{window::WindowBuilder, event_loop::EventLoop};
use std::time::Duration;
fn main() {
let event_loop = EventLoop::new();
let _window = WindowBuilder::new()
.build(&event_loop);
async_std::task::spawn_local(async {
// game loop goes here
loop {
// [update game state]
// [update frame buffer]
// [send render event with EventLoopProxy]
async_std::task::sleep(Duration::from_millis(16)).await;
// ^ note: I'll be using a different sleep function with Wasm
}
});
event_loop.run(move |event, _, control_flow| {
control_flow.set_wait();
match event {
// ...
_ => ()
}
});
}
The problem with this approach is that the game loop will never run. If I'm not mistaken, some asynchronous code in the main thread would need to be blocked (by calling .await) for the runtime to poll other Futures, such as the one spawned by the spawn_local function. I can't do this easily, since event_loop.run is not asynchronous.
Having time to await other events shouldn't be a problem, since the control flow is set to wait.
Testing this on native code, nothing inside the game loop ever runs. Testing this on Wasm code (with wasm_timer::Delay as the sleep function), the game loop does run, but at a very low framerate and with long intervals of halting.
Having explained my situation, I would like to ask: is it possible to do what I'm trying to do, and if it is, how would I approach it? I will also accept answers telling me how I could try to do this differently, such as by using web workers.
Thanks in advance!

QWebEngine: Execute runJavascript synchronously - QEventLoop blocks Javascript calls

Using Qt 5.15.2 - Execute runJavascript synchronously.
Problem:
I tried QtWebEngine - synchronously execute JavaScript to read function result
as a separate application and it worked fine, everything works as expected. But in my project on eventLoop->exec(), JS function is not executed(runJavascript is called).
QSharedPointer<QEventLoop> loop = QSharedPointer<QEventLoop>(new QEventLoop());
req.get()->m_pWebEngineView->page()->runJavaScript(req.get()->m_strJSFuncSignature, [loop](const QVariant& val) {
if (loop->isRunning()) {
loop->quit();
}
});
loop->exec(QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents);
Description:
We are creating a SINGLE-THREADED application that reads an XML file and creates HTML/Js/Css UI. I'm using CSS flex layout to layout the UI items. In code, I want to get the computed size and position synchronously in cpp.
To achieve synchronous communication to Javascript, I used the local event loop technique mentioned in QtWebEngine - synchronously execute JavaScript to read function result. The application hangs, Js function is not at all called.
Observation:
Without QEventLoop, all runjavascript calls are executed successfully one-after-other at the end i.e after all the statements in the program are executed.
With QEventLoop, all runjavascript calls are called but corresponding Js functions are not executed. Application hangs because runjavascript callback is not called.
Why this is happening? Kindly help.
Found the problem.
I was starting local QtEventLoop in the cpp function which is called from JS. The local QEventLoop in cpp function never quits because the Js function called in local QEventLoop is waiting for the current Js call to finish. Kind of deadlock.
Solution:
I queued the call coming from Js to cpp to global event loop.

Can we have asynchronous behaviour without threads?

Discussions on asynchronous features of a program generally move towards things like Futures,Promises etc which in turn involves multi threaded environment.
Is it possible to write an asynchronous program without resorting to multiple threads?
You can't have async without multiple workers.
Even when you don't control them directly (Eg: such as NodeJS), they still exists on the background. So on those languages, you can use them without explicitly working with threads / forks.
Eg:
var fs = require("fs");
fs.readFile('example.txt',function(err,data){
if(!err) {
console.log(data);
}
}); // 'fs.readFile' is async
console.log("something else"); // This will be executed right after the line above, and most likely the file ain't read yet.

How to halt execution in ActionScript

Is there any way to halt execution in ActionScript, such as a sleep() method?
I know that there is a setTimeout() method, but setTimeout() just sets up an event for deferred execution.
No. There is no sleep. Sorry.
See my answer here for options: ActionScript: pushing a closure onto the event stack?. It doesn't talk about sleeping, but I tried to provide an overview of deferred function calling.
You need to think in terms of not sleeping. Actionscript is not that kind of language. Because the flash player alternates between frame renders and code execution, sleeping in the code is always a bad idea, which is why there is no method to do it.
Having said that, you could achieve this by using the blocking method ExternalInterface.call, and in Javascript executing a blocking method (like XHR request).
Absolutely idiotic though, so don't do it.
Perhaps what you need is a Timer.
There's no way to pause all execution of an application as in PHP, but there are workarounds (unless you set a breakpoint or create a runtime error on purpose, don't think that's what you meant). Probably this is because usually flash applications are meant to execute all the scripts in less than one "frame".
It's common to be able to "pause" the animations of a website when the user unfocus it. This can be made by listening to Event.DEACTIVATE and then remove the ENTER_FRAME listeners and kill all ongoing processes.
You could also create a central EventDispatcher to replace the internal ENTER_FRAME, this way you seamlessly control speed of execution as well as pausing / resuming (won't stop executing scripts, nor asynchronous handlers such as loaders etc. though).
Yes, there is, though be aware of the 15 second script timeout. ( You can change that 15 second script timeout in the Publish Settings... )
I've found in the past that if you're looking for this functionality, you're doing something wrong :)
Whatever you're trying to accomplish is probably calling for an Event listener instead.
//adding this ENTER_FRAME event listener just to show that the script pauses for one
// second before the first frame executes
addEventListener( Event.ENTER_FRAME, onFrame );
function onFrame( event:Event ):void {
trace( "first frame occurs after pause of", getTimer() + " ms" );
removeEventListener( Event.ENTER_FRAME, onFrame );
};
var startTime:int = getTimer();
var pauseTime:int = 1000;
while( ( getTimer() - startTime ) < pauseTime ) {
//do nothing... we're effectively pausing here...
}

AS3 - How to do a synchronous load of an asynchronous call?

I have a function that loads a user object from a web service asynchronously.
I wrap this function call in another function and make it synchronous.
For example:
private function getUser():User{
var newUser:User;
var f:UserFactory = new UserFactory();
f.GetCurrent(function(u:User):void{
newUser = u;
});
return newUser;
}
UserFactory.GetCurrent looks like this:
public function GetCurrent(callback:Function):void{ }
But my understanding is there is no guarantee that when this function gets called, newUser will actually be the new user??
How do you accomplish this type of return function in Flex?
This way madness lies.
Seriously, you're better off not trying to force an asynchronous call into some kind of synchronous architecture. Learn how the event handling system works in your favour and add a handler for the result event. In fact, here's the advice straight from the flexcoders FAQ :
Q: How do I make synchronous data calls?
A: You CANNOT do synchronous calls. You MUST use the result event. No,
you can't use a loop, or setInterval or even callLater. This paradigm is
quite aggravating at first. Take a deep breath, surrender to the
inevitable, resistance is futile.
There is a generic way to handle the asynchronous nature of data service
calls called ACT (Asynchronous Call Token). Search for this in
Developing Flex Apps doc for a full description.
See my answer here:
DDD and Asynchronous Repositories
Flex and Flash Remoting is inherently asynchronous so fighting against that paradigm is going to give you a ton of trouble. Our service delegates return AsyncToken from every method and we've never had a problem with it.
If you want to ensure that the application doesn't render a new view or perform some other logic until the result/fault comes back, you could do the following:
Attach an event listener for a custom event that will invoke your "post result/fault code"
Make the async call
Handle the result/fault
Dispatch the custom event to trigger your listener from #1
Bear in mind this going to lead to a lot of annoying boilterplate code every time you make an async call. I would consider very carefully whether you really need a synchronous execution path.
You can't convert async call into sync one without something like "sleep()" function and as far as I know it is missing in AS3. And yes, it is not guaranteed that newUser would contain user name before return statement.
The AS3 port of the PureMVC framework has mechanisms for implementing synchronous operations in a Model-View-Controller context. It doesn't try to synchronize asynchronous calls, but it lets you add a synchronous application pattern for controlling them.
Here's an example implementation: PureMVC AS3 Sequential Demo.
In this example, five subcommands are run sequentially, together composing a whole command. In your example, you would implement getUser() as a command, which would call commandComplete() in the getURL() (or whatever) callback. This means the next command would be certain that the getUser() operation is finished.

Resources