I was wondering - when calling the org.eclipse.swt.browser.Browser method execute,
How is the return boolean determined?
When is the javaScript execution considered "successful"?
In particular, what happens when I start some asynchronous function and wait for the response?
Will the browser wait for the callback?
Is success based on an empty call stack and no errors?
Thanks in advance!
edit:
I just checked: the browser does not wait for callbacks to be called
As far as I can tell from digging in the source code, the result will be decided by either of the following methods:
Firefox: JS_EvaluateScriptForPrincipals
If the script compiles and executes successfully, *rval receives the value from the last-executed expression statement processed in the script, and JS_EvaluateScriptForPrincipals or JS_EvaluateUCScriptForPrincipals returns JS_TRUE. Otherwise it returns JS_FALSE, and the value left in *rval is undefined.
WebKit: JSEvaluateScript
The value that results from evaluating script, or NULL if an exception is thrown.
So it sounds like, if there's no error, true will be returned.
As far as the async part of your question is concerned, the Browser will not wait for the execution of the async task. What you can do, however, is define a BrowserFunction (as shown in this example) and call that method from JavaScript when you're done with your async task.
Related
Is there a way to tell if your function is being called synchronously or asynchronously?
For example, if I have a function shown below?
async function callMe() {
console.log("Am I called asynchronously?", callMe.isCalledAsync);
}
callMe(); // false
await callMe(); // true
The use case is I've needed to convert an existing function from sync to async and for testing purposes and because Chrome Debugger is reporting odd results, I want to check from inside the function that it's being called asynchronously. Another use case is if it's a public method than I want to make sure it's called using await.
Chrome Debugger seems to be aware of the await and async as shown in the screenshot below but either the debugger is incorrect or my code is incorrect or the JIT is not processing the calls async because Chrome Debugger is saying that only the first call is async but the recursive calls are not as shown in the image below.
We all know what you are supposed to do. But developers don't always do that; on purpose or on accident. And that's where dev tools like type checkers and autocomplete and intellisense and all development tools help assist and remind developers what's going on and what we might have missed. So having the feature doesn't preclude or prevent writing good code.
No, it's not possible for a function to determine if a caller used the await keyword. It's not even possible for a function to have knowledge from the runtime about whether or not a caller invoked it in an async context.
Because it's a public method I want to make sure it's called using await.
This is the responsibility of a compile-time lint rule, not of a function's runtime implementation. You (or the linter) will need to examine the source/AST of the calling code to make that determination.
In Javascript, the callback (of the awaited async function) runs only when the call stack is empty. If there are multiple callbacks, then they are queued (in the event loop queue) such that only 1 callback runs in its entirety before the next callback gets change to run.
In case of C# (assuming ConfigureAwait is not set to false - that is - the callabck will run in the same thread; also assuming there is syncronization context [winforms]):
Does the callback run immediately without waiting for call stack to be empty?
Suppose there are multiple callbacks queued, then while 1 callback is running, and another callback is ready for execution, then does the running callback suspend while the new callback wants to run? Or is it sequential?
The answer is that it depends on the current SynchronizationContext and, if that is null, the current TaskScheduler.
When the awaited Task completes, and you have configured the Awaitable to capture the context and recover on it, then almost certainly that continuation cannot continue immediately (the thread is likely busy executing something else). All that can be done is to schedule the continuation for later execution on the current SynchronizationContext, which is done by calling SynchronizationContext.Post().
How this Post method is implemented depends on the SynchronizationContext (which is abstract). If you are using WPF, the SynchronizationContext is a DispatcherSynchronizationContext. There, Post is implemented by a call to Dispatcher.BeginInvoke() with DispatcherPriority.Normal.
In other words, your continuation gets queued on the dispatcher for later execution with normal priority. Other delegates may have higher priority (e.g. DispatcherPriority.Input), but eventually your delegate gets executed on the dispatcher.
Two things to notice:
BeginInvoke simply queues your delegate. It does not execute it right away. In other words, queuing your delegate is really fast.
The above explanation should illustrate why async-await is just syntactic sugar. You could achieve all these calls yourself, but the compiler does it for you, making your code flow more naturally.
I was researching about javascript's async behaviour despite being single-threaded and I came after a comment stating that for this code:
request(..., function (error, response, body)
console.log('foo);
});
callAComputationallyIntensiveSynchronousFunctionThatTakesSixHoursToExecute();
console.log('bar');
'bar' will still come before 'foo' because Javascript always finishes the currently executing function first. An event will never interrupt a function.
I understand that a synchronous function execution has a higher priority over events, but I don't understand why 'bar' will be printed before 'foo'. From my reading, the async call should be made, and after that to fill the dead time before response is ready, it goes on and processes the other lines of code until it is ready, and then it should execute the callback function for the response and after that return to processing the code and so on.
The example above however states that even if the response would be ready long before the synchronous function finishes from executing, it still goes on and execute the next line of code. Why is that?
In JavaScript, everything is a function. There is no differentiation between a synchronous and an asynchronous function.
The only difference is the way you call these functions. So "sync"/"async" is an abstract concept for programmers which makes it easier to communicate.
How JavaScript actually works:
JavaScript has a queue of "functions" that are waiting to be executed. Everytime you create a new "asynchronous function", you add it to this queue. This happens, for example, when you do a setTimeout(), an ajax call, or simply a DOM-event like "onClick" triggered by the browser.
If a specific function is executed in JS, it will never be interrupted - it runs until it finished (returned). Only afterwards, the runtime (browser) takes a look at the queue, decides which function should be executed next, and then calls it - waiting it to be finished.
In your example above, the browser is currently executing the function that will print "bar". This execution cannot be interrupted before it finished, therefore "bar" is printed first. During the execution, however, a new asynchronous function is created and pushed to the execution-queue. Only after "bar" has been printed, the runtime will look in the queue, find the "foo"-function and execute it.
A negative side effect of this are long-running tasks. While such a function is executed, nothing else can be done by the browser. Not even rendering/updating the page. So if you have a piece of code that runs for, say, 10 seconds, the user cannot interact with the website until the function finished. The reason for that is that all user events, like mouse movenent, clicks and scroll events are queued and cannot be handled until the thread finishes the long running Task.
Multithreading with JavaScript
With HTML5, JavaScript now has the opportunity to use multiple threads using web workers though. But this is an entirely different topic and out of scope for this question. Just remember that it is theoretically possible.
For a couple of years, I was dealing with a part time problem where some DOM elements loaded with jquery html function were not accessible immediately after the function call (The behaviour was a bit like executing a function without waiting for the document ready event). Even though .html() is suppose to be synchronous, this SO answer (and also this one) suggests using the promise of the html function:
$('#divId').html("<h1>hello</h1>").promise().done(function(){
//Callback
});
A promise could make sense in such context but what intrigues me about this promise is that it will also be returned with every jquery's object:
$('#divId').promise().done(function(){
//Will also be called...
});
Since I couldn't find anything about it in the documentation of the html function, I was wondering what was the real purpose of this promise and if it is used correctly in this context.
The two methods are not related. The reason people often suggest this is because someone found out that they could use .promise().done() to make their code that has a race condition work. It worked for the same reason wrapping the same code in setTimeout(fn, 0) would make it work; it pushes it off to the callback queue to be ran later, likely after the browser performs a render or after some other async callback completes.
.html is synchronous, does not have a callback, and does not need a callback. However, the browser's renderer is asynchronous, so it won't render the change until after the callstack is clear. Using .promise pushes the callback off to the callback queue, thus running the code after a render which resolves the race condition or async logic flaw.
.promise() used on a jquery collection returns a promise that will resolve once all currently running jquery animations are complete. If there are no currently running animations, the promise will resolve immediately and the callback will be pushed to the callback queue to be called once the stack is clear.
It's nothing more than a bandaid. I'd suggest not using it, and instead fixing whatever async logic flaw is causing it to be the solution.
Very simple question: suppose I have the following js/jquery code
doSomething();
$.get(url, callback);
doSomethingElse();
I understand that right after the GET request is sent doSomethingElse() starts being executed. Now suppose that the server's reply arrives while doSomethingElse() is executing. What happens?
Does the callback run in a separate thread in parallel to doSomethingElse()?
Does the execution of doSomethingElse() pause until the callback runs and returns?
Does the callback only get called once doSomethingElse() has returned?
Thank you for any insight!
lara
No, JavaScript in web browsers is single-threaded, by design. That means that although the ajax call may start immediately (and be processed by another thread in the browser), your callback won't happen until the JavaScript interpreter is next idle. Things to do get queued up waiting for the interpreter to become idle and process them.
Edit Answering your specific questions:
Does the callback run in a separate thread in parallel to doSomethingElse()?
No, the callback will run in the same logical thread as doSomethingElse. (It would be implementation-dependant whether that's the same actual underlying OS thread, but you have no way of knowing and you don't care; logically, it's the same thread.)
Does the execution of doSomethingElse() pause until the callback runs and returns?
By default, the get will be asynchronous, so no. doSomethingElse initiates the request, but then continues. (It's possible to do a synchronous get via the underlying XmlHttpRequest mechanism, but it's a very bad idea -- tends to lock up the UI of the browser completely while the request is running, which is ugly -- and I don't know how you do it with jQuery.)
Does the callback only get called once doSomethingElse() has returned?
With an asynchronous get (the usual kind), you can be certain that doSomethingElse will finish before the callback gets called, yes. This is because the JavaScript interpreter will only do one thing at a time, and it doesn't switch to doing a new thing until it's done with the current one. So although doSomethingElse triggers the get (and the get may be processed by other, non-JavaScript threads in parallel to JavaScript), your callback won't happen until after the interpreter is done with doSomethingElse and anything that called it.
I wouldn't be surprised if at some point we start getting multiple threads in browser-based JavaScript, but if and when we do, it'll have to be explicit, since we all happily assume one thread for the moment.
To all intents and purposes there are no threads in JS, therefore execution does not happen on a separate thread.
What web APIs do do is make use of asynchronous callbacks, and that's what is happening here -- get() returns immediately, your callback function will be called once the load is complete and there is no other JS code running.
No, there is only one thread of control for Javascript. The currently executing function will continue running until it completes, then the callback will be invoked once it is ready.
So to specifically answer your question, the callback only gets called once doSomethingElse() has returned. Assuming, of course, that the GET request is successful - if an error occurrs then the callback will never be executed.
Here is a pretty good article that illustrates how this works.
http://www.javascriptkata.com/2007/06/12/ajax-javascript-and-threads-the-final-truth/
I honestly don't know the answer, but I wouldn't place any code in doSomethingElse() that is dependent on something that callback() does. I know that doSomethingElse() will always run first, but as far as timing/thread issues I'm not sure.