XCode has webkit built in, and XCode can issue a JavaScript command and receive a return value. All that is good - except when JavaScript has a callback function like with executeSql.
How do you write a function that doesn't return until the callback has been called?
Do you wrap it in another function maybe?
There are two solutions - you may either write your entire program in continuation passing style or you may use trampolines to simulates real continuations.
If you want to use continuation passing style then I suggest you first read the following StackOverflow thread: What's the difference between a continuation and a callback?
Continuation passing style can be a pain to write. Fortunately there are JavaScript preprocessors like jwacs (Javascript With Advanced Continuation Support) which ease writing such code: http://chumsley.org/jwacs/
The second option (using trampolining) currently only works in Firefox and Rhino. Sorry XCode. You can read more about trampolining here: Trampolines in Javascript and the Quest for Fewer Nested Callbacks
If it interests you then I've written a small fiber manager for JavaScript that allows you to call asynchronous functions synchronously: https://github.com/aaditmshah/fiber
May I suggest checking it periodically?
var executeSqlIsDone = false;
executeSql({
callback: someCallbackFunction();
});
waitUntilCallbackIsFinished();
//continue processing
function someCallbackFunction()
{
executeSqlIsDone = true;
}
function waitUntilCallbackIsFinished()
{
if(executeSqlIsDone === false)
{
setTimeout(waitUntilCallbackIsFinished, 100); //some low value
}
//else - do nothing. Wait.
}
Also look into
Related
Is there any easy way in which we can know the sequence in which methods are called in runtime?
Example: In my JS File, I have around 15 methods. There are some Asynchronous calls. With Async calls we never know the sequence in which they are called and executed. So : I want to know, if there is a way in which we can debug (using developer tools, IE\Chrome\FF) .. any tool which tells me which async call was called first and the order in which they are called.
Thanks.
Using Chrome developer tools, you can use the Sources panel to debug javascript.
On the right side, you can add breakpoints for various types of events including XHR Breakpoints.
The execution will stop when the breakpoint is triggered and you can step through the execution flow.
I'm pretty sure Firefox and IE have similar tools.
As ryan S suggested, using console.log can be a way of checking the sequence of code execution. So you can add console.log("1: [description]").
Beside the given answers, you can also write a utility that will make wrap the methods of an object with logging:
It would be like this:
function addLogging(object) {
Object.keys(object).forEach(function (key) {
if (typeof object[key] === 'function') {
var originalFn = object[key];
object[key] = function () {
console.log('before calling', key);
var result = originalFn.apply(this, arguments);
console.log('after calling', key);
return result;
}
}
});
}
You can use lodash wrap method to help you.
Long ago I have answered a question regarding something similar like the above code: jQuery logger plugin
It didn't handle constructors perfectly, so it had problems like that. Here's the fixed resulting code.
You can also have a look at sinon.js, it provides spies and it can determine order of call of spied functions. But it might be a bit too much for just this, and it's might slow things down a little.
This method is a common thing done in aspect oriented programming. You can search about it and maybe try to use a AOP library. meld is a popular one.
Also instead of console.log in chrome you can use console.timeline, which gives you great visibility if used correctly.
I'm just curious if it is possible in Firefox addon to call a function that would wait to callback in asynchronous function call. It could be potentially useful.
For example
function async_func(callback) {
...
callback(2);
}
function callback_foo(x) { return x*x; }
var results = Sync.wait_for_async_callback(async_func, callback_foo);
// now, results is 2*2 = 4
....
I know that javascript engine is generally one-thread so it's not allowed to run simultaneously synchronous waiting, sleeping in Sync.wait_for_async_callback and calling callback in async_func or functions called from async_func.
But I've found by chance this article that may point that it would be possible. However I can't find needed module for this (a Sync.js file). Link on that article doesn't seems to be useful (errors in server-side code?) Firefox code on Mozilla-central doesn't know this file.
Maybe Web Workers or nsIThreadManager could be other way to convert async to sync call.
So I found the Sync.js module. It uses synchrounous waiting for next events by processNextEvent until callback will be fired:
let thread = Cc["#mozilla.org/thread-manager;1"].getService().currentThread;
while (async callback not fired yet)
thread.processNextEvent(true);
This trick seems to work but according to Marco Bonardo it is bad choice (crashes?)
This is done with Promises, read {this documentation](https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm) which is based on this specification.
Sorry about the title but could not come up with anything really informative and concise.
My situation is that I am launching a setTimeout and I want it to be able to run in the middle of a JS function (it is used to get around the issue with injecting GM functions into the web page).
unsafeWindow.testG = function(key, dValue){
var rValue;
setTimeout(function(){rValue = GM_getValue(key, dValue);}, 0);
alert(rValue);
alert(rValue);
return(rValue);
}
In the three tests rValue is still undefined (which makes sense because JS is single threaded for the most part).
So I have 2 solutions I have thought of.
Favourite:
Is there anyway to tell JS to sleep in the middle of a function and work on background stuff (like Timeouts)?
Other:
Does anyone know when this timeout will be called? Maybe after this function execution but before whatever called it starts up again?
In that case making rValue global would solve the issue (but make slightly messier coding).
Or will it wait until all JS is done executing?
In that case I would possibly need another setTimeout to process the result.
There is no way what you're asking for can be accompished. Until HTML5 is a wide spread standard, you can't do what you're asking without thinking asynchronously.
For example :
unsafeWindow.testG = function(key, dValue, callback){
var rValue;
setTimeout(function(){
rValue = GM_getValue(key, dValue);
callback(rValue);
}, 0);
}
and call this with a callback :
unsafewindow.testG(key, dValue, function(rValue) {
alert(rValue);
});
alert("foo");
For the last sippet, "foo" will be echoed before rValue, because testG will execute the timeout function only when the Javascript thread is available, or only when there's no other script running.
To answer your first question, there is no 'sleep' function in JS. In fact, there is a site devoted to trying to create one: http://www.devcheater.com/ The conclusion: you cannot.
If what you'd like to do is make the rest of your code run later, you can put that code in a function and setTimeout().
Of course, the usual way to handle the sort of scenario you have set up is with callbacks. Since you're basically waiting for the thing in setTimeout to happen, you can have it call the rest of your code whenever it's done. For example:
var fartResult
function waitAMinuteThenFart (callback) {
function fart () {
fartResult = 'fart'
callback(fartResult)
}
setTimeout(fart, 1000*60)
}
waitAMinuteThenFart(function (result) { alert(result) })
if i fire up 2 functions like this:
prepare_data();
read_data();
then i guess they are running at the same time. but as you can see function two is depending on the first one, so how can i make the latter one run after the first one is completed?
Javascript, and most other languages, run code sequentially.
Therefore, they will not both run at the same time.
In fact, it is not possible to run two different pieces of Javascript code at the same time. However, in many other languages, it is possible using threads.
However, if they make AJAX calls, the corresponding server-side code called by both functions will run simultaneously.
To prevent that, you'll need to make the first function accept a callback parameter and pass it the second function.
I'm assuming the first call makes some kind of asynchronous call that the second relies upon because otherwise the two functions will execute sequentially.
If so you need to do the second in the callback from the first. For example, in jQuery:
function prepare_data() {
$("#data").load("/load_data.php", function() {
read_data();
});
}
It's impossible to say how you should solve this without more information on whether you're using vanilla Javascript or a particular library. I'd strongly suggest using a library of some sort for AJAX however.
May be you want to call Second function after first function function to be successfully executed, if so, then you can do this by this
$('button').click(function()
{
function1(someVariable, function() {
function2(someOtherVariable);
});
});
function function1(param, callback) {
alert('Now first function will be called.');
callback();
}
#SLaks
In fact, it is not possible to run two
different pieces of Javascript code at
the same time. However, in many other
languages, it is possible using
threads.
Is this completely correct? cant you run javascript parallely using web workers ?
http://www.w3.org/TR/2009/WD-workers-20090423/
https://developer.mozilla.org/En/Using_web_workers
I'm working with a JavaScript API where most of the functions are asynchronous. The API is the WebKit JavaScript Database API which is a binding to a subset of functionality to manipulate SQLite3 databases. I understand the design decision to make things async as to not block and provide a responsive user interface. In my situation I know that my usage of the async API calls will execute fast. Since this is the case I'd like to provide my developers a cleaner and easier to use wrapper API that forces synchronous calls.
Here's the async call
db.executeSql(sqlStatement, function(result) {
// do something with result
});
And here's what I'd like to be able to do
var result = dbWrapper.executeSql(sqlStatement);
// do something with result
Is there a design pattern/way to do this? A written or linked to code example is preferred. The target platform/broswer is Mobile Safari on the iPhone.
Thank you
Sorry, JavaScript does not provide the language primitives (eg. threads or coroutines) to make asynchronous things act synchronously or vice-versa.
You generally* get one thread of execution only, so you can't get a callback from a timer or XMLHttpRequest readystatechange until the stack of calls leading to the creation of the request has completely unravelled.
So in short, you can't really do it; the approach with nested closures on the WebKit page you linked is the only way I know of to make the code readable in this situation.
*: except in some obscure situations which wouldn't help you and are generally considered bugs
StratifiedJS allows you to do exactly that.
There's even an article on how to apply it on browser storage:
http://onilabs.com/blog/stratifying-asynchronous-storage
And this is the Stratified JavaScript library it uses https://gist.github.com/613526
The example goes like:
var db = require("webdatabase").openDatabase("CandyDB", ...);
try {
var kids = db.executeSql("SELECT * FROM kids").rows;
db.executeSql("INSERT INTO kids (name) VALUES (:name);", [kids[0]]);
alert("done");
} catch(e) {
alert("something went wrong");
}
maybe a bit late, but the tech didn't exist back then ;)
You can try something like:
function synch()
{
var done = false;
var returnVal = undefined;
// asynch takes a callback method
// that is called when done
asynch(function(data) {
returnVal = data;
done = true;
});
while (done == false) {};
return returnVal;
}
But that may freeze your browser for the duration of the asynch method...
Or take a look at Narrative JavaScript: Narrative JavaScript is a small extension to the JavaScript language that enables blocking capabilities for asynchronous event callbacks. This makes asynchronous code refreshingly readable and comprehensible.
http://neilmix.com/narrativejs/doc/index.html
Mike
if you are using jQuery Ajax :
$.ajax()
you can set the attribute of asynch to false ,
and then you will have a synch ajax request to the server.
We are using GWT RPC which also has an async API. The solution that we are currently using to make several async calls in serial is call chaining:
callA(function(resultA) {
callB(resultA, function(resultB) {
callC(); //etc.
});
});
This nested approach achieves what you want but it is verbose and hard to read for newcomers. One of the approaches that we have investigated is adding the calls that we need to make to a stack and executing them in order:
callStack = [
callA(),
callB(),
callC()
];
callStack.execute();
Then the callstack would manage:
Invoking the calls in serial (i.e. the wiring in the first example)
Passing the result from one call forward to the next.
However, because Java doesn't have function references, each call on the call stack would require an anonymous class so we stopped short of such a solution. However, you may have more success in javascript.
Good luck!
This doesn't actually implement synchronous operation of the db query, but this was my solution for easy management. Basically use the calling function as the callback function, and test for the results argument. If the function receives results, it parses them, if not, it sends itself as a callback to the query method.
render: function(queryResults){
if (typeof queryResults != 'undefined'){
console.log('Query completed!');
//do what you will with the results (check for query errors here)
} else {
console.log('Beginning query...');
this.db.read(this.render); //db.read is my wrapper method for the sql db, and I'm sending this render method as the callback.
}
}
I am not sure if this is the right place but I cam here searching for answers to making an synchronous calls in Firefox. the solution would be to remove onreadystatechange callback and do a direct call.
This is what I had found and my solution
synchronous call back with rest service