So I have been developing some codes using AWS Lambda with NodeJS 6.10. Because of my lack of knowledge in integration testing (don't worry, the unit tests are done), I didn't test my code. Of course, I missed a bug that caused two sleepless nights. It keeps running even after I put in this
return workerCallback(err);
I thought it would stop the function from running other codes past the if clause because I returned it. Anyway, I was able to fix my issue by adding a return just after the asynchronous function
SQSService.deleteMessage
is called. The rest of the codes did not run and the lambda function ran and ended as expected.
Here are now the code that works as expected.
function myFoo(currentRequest,event, workCallback){
var current_ts = moment();
var req_ts = moment(currentRequest.request_timestamp);
if (req_ts.diff(current_ts, 'minutes') > 5) {
SQSService.deleteMessage(event.ReceiptHandle, function(err, data){
if (err) {
return workerCallback(err);
} else {
return workerCallback(null, "Request stale! Deleting from queue...");
}
}); //end of SQS Service
return; //This line... this line!
}
/* Codes below will execute because the code above is asynchronous
but it should not as the asynchronous code above is a terminator function
from a business logic point of view
*/
//more codes that will run should currentRequest.request_timestamp is 5 minutes past
}
Can someone please guide me on how to test this code or create a test that would at least prevent me from doing the same mistake again? I'd like to avoid these mistakes from happening again by testing. Thanks!
(I'm moving it to an answer so the comments thread doesn't fill up - and so I can type more).
The key is to get the proper grasp of async-ness in your code. myFoo seems to be asynchronous, so you need to decide whether all errors or failure modes should be handled as errors passed to its callback handler, or whether some types of error should return synchronous errors to the caller of myFoo itself. My general approach is, if any errors are going through the callback handler, to have them all go there - with the minor exception of certain types of bad-coding errors (e.g. passing in things of the wrong type, or passing in null for arguments that should always have variables) which I might throw Error() for. But if this kind of error (project_ref_no == null) is the kind of error that you should handle gracefully, then I'd probably pass it through to the error handler. The general idea is that, when you call myFoo, and it returns, all you know is that some work is going to get done at some point, but you don't know what is going to happen (and won't get a result in the response) - the response will come back later in the call to the callback handler).
But, more importantly, it's key to understand what code is being run immediately, and what code is in a callback handler. You got tripped up because you mentally imagines the internally generated callback handler (passed to SQSService.deleteMessage) was being run when you called myFoo.
As for testing strategy, I don't think there's a silver bullet to the issue of mistaking asynchronous calls (with callback handlers) with code that is run synchronously. You could sprinkle assertions or throw Error()'s all over the place (where you think code should never get to), but that'd make your code ridiculous.
Typescript helps with this a bit, because you can define a function return type, and your IDE should give you a warning if you've got code paths that don't return something of that type (something most/all? typed languages give you) - and that would help somewhat, but it won't catch all cases (e.g. functions that return void).
If you're new to javascript and/or javascript's asynchronous models, you might check out the following link:
https://medium.com/codebuddies/getting-to-know-asynchronous-javascript-callbacks-promises-and-async-await-17e0673281ee
Related
For the past two days I have been working with chrome asynchronous storage. It works "fine" if you have a function. (Like Below):
chrome.storage.sync.get({"disableautoplay": true}, function(e){
console.log(e.disableautoplay);
});
My problem is that I can't use a function with what I'm doing. I want to just return it, like LocalStorage can. Something like:
var a = chrome.storage.sync.get({"disableautoplay": true});
or
var a = chrome.storage.sync.get({"disableautoplay": true}, function(e){
return e.disableautoplay;
});
I've tried a million combinations, even setting a public variable and setting that:
var a;
window.onload = function(){
chrome.storage.sync.get({"disableautoplay": true}, function(e){
a = e.disableautoplay;
});
}
Nothing works. It all returns undefined unless the code referencing it is inside the function of the get, and that's useless to me. I just want to be able to return a value as a variable.
Is this even possible?
EDIT: This question is not a duplicate, please allow me to explain why:
1: There are no other posts asking this specifically (I spent two days looking first, just in case).
2: My question is still not answered. Yes, Chrome Storage is asynchronous, and yes, it does not return a value. That's the problem. I'll elaborate below...
I need to be able to get a stored value outside of the chrome.storage.sync.get function. I -cannot- use localStorage, as it is url specific, and the same values cannot be accessed from both the browser_action page of the chrome extension, and the background.js. I cannot store a value with one script and access it with another. They're treated separately.
So my only solution is to use Chrome Storage. There must be some way to get the value of a stored item and reference it outside the get function. I need to check it in an if statement.
Just like how localStorage can do
if(localStorage.getItem("disableautoplay") == true);
There has to be some way to do something along the lines of
if(chrome.storage.sync.get("disableautoplay") == true);
I realize it's not going to be THAT simple, but that's the best way I can explain it.
Every post I see says to do it this way:
chrome.storage.sync.get({"disableautoplay": true, function(i){
console.log(i.disableautoplay);
//But the info is worthless to me inside this function.
});
//I need it outside this function.
Here's a tailored answer to your question. It will still be 90% long explanation why you can't get around async, but bear with me — it will help you in general. I promise there is something pertinent to chrome.storage in the end.
Before we even begin, I will reiterate canonical links for this:
After calling chrome.tabs.query, the results are not available
(Chrome specific, excellent answer by RobW, probably easiest to understand)
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference (General canonical reference on what you're asking for)
How do I return the response from an asynchronous call?
(an older but no less respected canonical question on asynchronous JS)
You Don't Know JS: Async & Performance (ebook on JS asynchronicity)
So, let's discuss JS asynchonicity.
Section 1: What is it?
First concept to cover is runtime environment. JavaScript is, in a way, embedded in another program that controls its execution flow - in this case, Chrome. All events that happen (timers, clicks, etc.) come from the runtime environment. JavaScript code registers handlers for events, which are remembered by the runtime and are called as appropriate.
Second, it's important to understand that JavaScript is single-threaded. There is a single event loop maintained by the runtime environment; if there is some other code executing when an event happens, that event is put into a queue to be processed when the current code terminates.
Take a look at this code:
var clicks = 0;
someCode();
element.addEventListener("click", function(e) {
console.log("Oh hey, I'm clicked!");
clicks += 1;
});
someMoreCode();
So, what is happening here? As this code executes, when the execution reaches .addEventListener, the following happens: the runtime environment is notified that when the event happens (element is clicked), it should call the handler function.
It's important to understand (though in this particular case it's fairly obvious) that the function is not run at this point. It will only run later, when that event happens. The execution continues as soon as the runtime acknowledges 'I will run (or "call back", hence the name "callback") this when that happens.' If someMoreCode() tries to access clicks, it will be 0, not 1.
This is what called asynchronicity, as this is something that will happen outside the current execution flow.
Section 2: Why is it needed, or why synchronous APIs are dying out?
Now, an important consideration. Suppose that someMoreCode() is actually a very long-running piece of code. What will happen if a click event happened while it's still running?
JavaScript has no concept of interrupts. Runtime will see that there is code executing, and will put the event handler call into the queue. The handler will not execute before someMoreCode() finishes completely.
While a click event handler is extreme in the sense that the click is not guaranteed to occur, this explains why you cannot wait for the result of an asynchronous operation. Here's an example that won't work:
element.addEventListener("click", function(e) {
console.log("Oh hey, I'm clicked!");
clicks += 1;
});
while(1) {
if(clicks > 0) {
console.log("Oh, hey, we clicked indeed!");
break;
}
}
You can click to your heart's content, but the code that would increment clicks is patiently waiting for the (non-terminating) loop to terminate. Oops.
Note that this piece of code doesn't only freeze this piece of code: every single event is no longer handled while we wait, because there is only one event queue / thread. There is only one way in JavaScript to let other handlers do their job: terminate current code, and let the runtime know what to call when something we want occurs.
This is why asynchronous treatment is applied to another class of calls that:
require the runtime, and not JS, to do something (disk/network access for example)
are guaranteed to terminate (whether in success or failure)
Let's go with a classic example: AJAX calls. Suppose we want to load a file from a URL.
Let's say that on our current connection, the runtime can request, download, and process the file in the form that can be used in JS in 100ms.
On another connection, that's kinda worse, it would take 500ms.
And sometimes the connection is really bad, so runtime will wait for 1000ms and give up with a timeout.
If we were to wait until this completes, we would have a variable, unpredictable, and relatively long delay. Because of how JS waiting works, all other handlers (e.g. UI) would not do their job for this delay, leading to a frozen page.
Sounds familiar? Yes, that's exactly how synchronous XMLHttpRequest works. Instead of a while(1) loop in JS code, it essentially happens in the runtime code - since JavaScript cannot let other code execute while it's waiting.
Yes, this allows for a familiar form of code:
var file = get("http://example.com/cat_video.mp4");
But at a terrible, terrible cost of everything freezing. A cost so terrible that, in fact, the modern browsers consider this deprecated. Here's a discussion on the topic on MDN.
Now let's look at localStorage. It matches the description of "terminating call to the runtime", and yet it is synchronous. Why?
To put it simply: historical reasons (it's a very old specification).
While it's certainly more predictable than a network request, localStorage still needs the following chain:
JS code <-> Runtime <-> Storage DB <-> Cache <-> File storage on disk
It's a complex chain of events, and the whole JS engine needs to be paused for it. This leads to what is considered unacceptable performance.
Now, Chrome APIs are, from ground up, designed for performance. You can still see some synchronous calls in older APIs like chrome.extension, and there are calls that are handled in JS (and therefore make sense as synchronous) but chrome.storage is (relatively) new.
As such, it embraces the paradigm "I acknowledge your call and will be back with results, now do something useful meanwhile" if there's a delay involved with doing something with runtime. There are no synchronous versions of those calls, unlike XMLHttpRequest.
Quoting the docs:
It's [chrome.storage] asynchronous with bulk read and write operations, and therefore faster than the blocking and serial localStorage API.
Section 3: How to embrace asynchronicity?
The classic way to deal with asynchronicity are callback chains.
Suppose you have the following synchronous code:
var result = doSomething();
doSomethingElse(result);
Suppose that, now, doSomething is asynchronous. Then this becomes:
doSomething(function(result) {
doSomethingElse(result);
});
But what if it's even more complex? Say it was:
function doABunchOfThings() {
var intermediate = doSomething();
return doSomethingElse(intermediate);
}
if (doABunchOfThings() == 42) {
andNowForSomethingCompletelyDifferent()
}
Well.. In this case you need to move all this in the callback. return must become a call instead.
function doABunchOfThings(callback) {
doSomething(function(intermediate) {
callback(doSomethingElse(intermediate));
});
}
doABunchOfThings(function(result) {
if (result == 42) {
andNowForSomethingCompletelyDifferent();
}
});
Here you have a chain of callbacks: doABunchOfThings calls doSomething immediately, which terminates, but sometime later calls doSomethingElse, the result of which is fed to if through another callback.
Obviously, the layering of this can get messy. Well, nobody said that JavaScript is a good language.. Welcome to Callback Hell.
There are tools to make it more manageable, for example Promises and async/await. I will not discuss them here (running out of space), but they do not change the fundamental "this code will only run later" part.
Section TL;DR: I absolutely must have the storage synchronous, halp!
Sometimes there are legitimate reasons to have a synchronous storage. For instance, webRequest API blocking calls can't wait. Or Callback Hell is going to cost you dearly.
What you can do is have a synchronous cache of the asynchronous chrome.storage. It comes with some costs, but it's not impossible.
Consider:
var storageCache = {};
chrome.storage.sync.get(null, function(data) {
storageCache = data;
// Now you have a synchronous snapshot!
});
// Not HERE, though, not until "inner" code runs
If you can put ALL your initialization code in one function init(), then you have this:
var storageCache = {};
chrome.storage.sync.get(null, function(data) {
storageCache = data;
init(); // All your code is contained here, or executes later that this
});
By the time code in init() executes, and afterwards when any event that was assigned handlers in init() happens, storageCache will be populated. You have reduced the asynchronicity to ONE callback.
Of course, this is only a snapshot of what storage looks at the time of executing get(). If you want to maintain coherency with storage, you need to set up updates to storageCache via chrome.storage.onChanged events. Because of the single-event-loop nature of JS, this means the cache will only be updated while your code doesn't run, but in many cases that's acceptable.
Similarly, if you want to propagate changes to storageCache to the real storage, just setting storageCache['key'] is not enough. You would need to write a set(key, value) shim that BOTH writes to storageCache and schedules an (asynchronous) chrome.storage.sync.set.
Implementing those is left as an exercise.
Make the main function "async" and make a "Promise" in it :)
async function mainFuction() {
var p = new Promise(function(resolve, reject){
chrome.storage.sync.get({"disableautoplay": true}, function(options){
resolve(options.disableautoplay);
})
});
const configOut = await p;
console.log(configOut);
}
Yes, you can achieve that using promise:
let getFromStorage = keys => new Promise((resolve, reject) =>
chrome.storage.sync.get(...keys, result => resolve(result)));
chrome.storage.sync.get has no returned values, which explains why you would get undefined when calling something like
var a = chrome.storage.sync.get({"disableautoplay": true});
chrome.storage.sync.get is also an asynchronous method, which explains why in the following code a would be undefined unless you access it inside the callback function.
var a;
window.onload = function(){
chrome.storage.sync.get({"disableautoplay": true}, function(e){
// #2
a = e.disableautoplay; // true or false
});
// #1
a; // undefined
}
If you could manage to work this out you will have made a source of strange bugs. Messages are executed asynchronously which means that when you send a message the rest of your code can execute before the asychronous function returns. There is not guarantee for that since chrome is multi-threaded and the get function may delay, i.e. hdd is busy.
Using your code as an example:
var a;
window.onload = function(){
chrome.storage.sync.get({"disableautoplay": true}, function(e){
a = e.disableautoplay;
});
}
if(a)
console.log("true!");
else
console.log("false! Maybe undefined as well. Strange if you know that a is true, right?");
So it will be better if you use something like this:
chrome.storage.sync.get({"disableautoplay": true}, function(e){
a = e.disableautoplay;
if(a)
console.log("true!");
else
console.log("false! But maybe undefined as well");
});
If you really want to return this value then use the javascript storage API. This stores only string values so you have to cast the value before storing and after getting it.
//Setting the value
localStorage.setItem('disableautoplay', JSON.stringify(true));
//Getting the value
var a = JSON.stringify(localStorage.getItem('disableautoplay'));
var a = await chrome.storage.sync.get({"disableautoplay": true});
This should be in an async function. e.g. if you need to run it at top level, wrap it:
(async () => {
var a = await chrome.storage.sync.get({"disableautoplay": true});
})();
I am fairly new to Meteor, fibers and futures and I am trying to understand how Meteor methods work. It is my understanding that each method call from a client would wait for a previous one to finish. This belief is mostly based on the documentation of the this.unblock() function in the Meteor docs. However, when I try setting up a simple example with a Meteor.setTimeout() call this does not seem to be a correct assumption.
methodCall.js:
if (Meteor.isClient) {
Template.hello.events({
'click button': function () {
Meteor.call('test', function(error, result){
});
}
});
}
if (Meteor.isServer) {
Meteor.methods({
test: function(){
console.log("outside");
Meteor.setTimeout(function(){
console.log("inside");
return 'done';
}, 2000);
}
});
}
When triggering the 'click button' event several times the terminal output is as follows:
outside
outside
outside
outside
inside
inside
inside
inside
and not alternating between outside and inside as I would expect. I think there is a very relevant bit of information on Meteor.setTimeout() I am missing, but I could not find anything in the documentation indicating this behaviour. What am I missing and is there a way of making the Meteor method invocations from a client wait until a previous invocation is finished before starting the execution of the next?
I found this question on SO which seemed promising, but the question is more focused on blocking the possibility to call the method from the client side. Likewise, the accepted answer is not completely satisfying as it focuses on making subsequent calls skip certain code blocks of the Meteor method instead of waiting for the first invocation to finish. This very well be the answer I guess, but I really want to understand why the method call is not blocked in the first place as I feel the Meteor documentation indicates.
The answer is that the setTimeout callback is executed outside the fiber in which the method is running. What that means is that the method actually finishes execution (returning undefined) before the setTimeout callback is ever invoked, and you get the behavior you observed.
To provide a better test (and for an example of using asynchronous functions in methods), try this:
if (Meteor.isServer) {
var Future = Npm.require('fibers/future');
Meteor.methods({
test: function(){
var fut = new Future();
console.log("outside");
Meteor.setTimeout(function(){
console.log("inside");
fut.return('done');
return 'done';
}, 2000);
return fut.wait();
}
});
}
The return value from your setTimeout callback doesn't actually go anywhere, it just curtails that function (i.e. the callback, not the method). The way it's written above, the Future object, fut, is supplied with the return value once the callback runs, but the main method function (which is still running in its original fiber) is prevented from returning until that value has been supplied.
The upshot is that unless you unblock this method, you will get the expected output as the next method invocation won't start until the previous one has returned.
UPDATE
In general, anything with a callback will have the callback added to the event loop after the current Fiber is closed, so timeouts, HTTP calls, asynchronous DB queries - all of these fall into this category. If you want to recreate the environment of the method within the callback, you need to use Meteor.bindEnvironment otherwise you can't use any Meteor API functionality. This is an old, but very good video on the subject.
I'm having to make a Javascript API that is the public interface to a C-based API that has enumerations and required parameters. Javascript, being a loosely typed language, wouldn't offer the same kind of compiler warnings one might get when using a C-based API.
My question is when making a Javascript wrapper around the C API, is it expected in the Javascript culture that one would receive a TypeError when passing invalid data or would it be more expected for the API to output a message to the console and ignore the error?
Here's some sample code for the API...
var Foo = (function() {
var foo = {
Enum: {
First: {value: 0},
Second: {value: 1},
Third: {value: 2}
},
bar: function(eenoom, aNumber) {
if (!eenoom) {
throw new TypeError("bar: You must specify the 'eenoom' parameter");
return;
}
if (!aNumber || typeof aNumber != 'number') {
throw new TypeError("bar: You must specify the 'aNumber' parameter (as a number)");
return;
}
for (var key in foo.Enum) {
if (foo.Enum.hasOwnProperty(key)) {
if (foo.Enum[key] === eenoom) {
console.log("You did it!");
return;
}
}
}
throw new TypeError("bar: You must use the Foo.Enum enumeration");
}
}
// So no one can mess with our enums
Object.freeze(foo.Enum);
return foo;
})();
Foo.bar(Foo.Enum.First, 20);
Foo.bar({value: 0}, 20); // Throws a TypeError
Note the use of TypeError. Is this an expected way for a Javascript API to behave?
I mainly do the following:
In synchronous public APIs I always check parameters and throw the appropriate error. Not only TypeError but also other errors as appropriate.
Generally I throw errors in exceptional cases - i.e. not fitting the thought-out execution flow.
In asynchronous APIs I report errors via an error callback/reject function.
I think console.log(...) and go on is not a good idea. If the call did not met the pre-conditions of the API, the API contract is broken from the very start. (Unless the contract is, specifically "yes, I can handle bad input" which is quite decadent.)
In this case nothing that you do afterwards will be correct. So throw an error and break off.
As an API consumer I'd be grateful for a thrown error with a good stack trace and a meaningful error message - much more that for just a meaningfull error message in the console (which I may or may not notice).
If the programmer has written code that will never work (not provided required parameters, sent the wrong type or order of parameters, etc...), then you want the code to fail immediately, fail visibly, clearly tell the programmer what is wrong and provide a stack trace that shows exactly where the offending code is.
The cleanest way to do that in Javascript is by throwing an appropriate type of error with a meaningful description. The very first time this code is executed, it will fail and the developer will immediately know they have done something wrong. This is what you want. Anything else increases the chances that the developer does not immediately realize the programming mistake they've made or even if they realize something isn't working, it might take them significantly longer to figure out why it isn't working.
A console.log() statement has these drawbacks:
It may not be seen immediately or at all.
It doesn't provide a stack trace so it may not be obvious what specific part of the caller's code is causing the error.
Since the app may not fail noticeably, it may appear that nothing is wrong or nothing serious is wrong when in reality there is a major programming mistake that must be fixed.
I am new to JavaScript and I have a question regarding asynchronous functions when I read about it in the book "JavaScript the good parts":
I understand that the following code will be executed synchronously and may cause delay:
request = prepare_the_request();
response = send_request_synchronously(request);
display(response);
However, the following code is said to be executed asynchronously:
request = prepare_the_request();
send_request_asynchronously(request, function(response){
display(response);
});
How does the compiler(or interpreter? I am not sure how JavaScript is interpreted) know that the second block of code is supposed to be executed asynchronously?
Thank you in advance.
(If the question is not clear please comment and I am sorry for not expressing it clearly.)
Compiler/Interpreter doesn't know that, and actually doesn't care about it. On multiprocess operating systems, two or more threads can run concurrently, and Javascript's XMLHTTPRequest object allows to run the request in a separate thread. This way, Javscript starts the thread, but since it is running in a separate thread, it doesn't wait and continue with next command.
I'll be completely honest... the first time I read that same Callbacks section on page 53 of Javascript, the good parts, I also made the same assumption as you did hahaha, though only later did I find out what the author meant.
Your previous statement isn't actually correct:
However, the following code is said to be executed asynchronously:
Before the Author displays the code with the callback function, he says the following paragraph:
A better approach is to make an asynchronous request, providing a
callback function that will be invoked when the server’s response is
received. An asynchronous function returns immediately, so the client
isn’t blocked:
The important part here is: ...make an asynchronous request, PROVIDING a callback function...
The author was trying to make the point that you could make a function like:
send_request_asynchronously(request, function (response) {
display(response);
});
that doesn't execute function (response) {display(response);} at the time the code is run through the interpreter, but rather some time in the future when a call to send_request_asynchronously is made AND later on in the code you could make it asynchronous. The very code itself has nothing asynchronous about it. It's designed to be called asynchronously later.
The "PROVIDING a callback function" is key to infering this is what the author meant. If you notice, there is no trailing () after the callback function. If you did have a trailing () like so:
send_request_asynchronously(request, function (response) {
display(response);
}());//<--- right here
then the function would execute right then and there when the interpreter was reading through that portion of the code, hence forcing the system to be Synchronous, where as by not including (), you open the door for it to be Asynchronous in the future by implementing code with Asynchronous features that then call this function.
As a final important point, lets remember that this is what makes a callback function a callback function. It is not being invoked when you include the function in the parameter. So for instance, if I make a function called salutations:
var salutations = function (hello(){alert('hi')})
{
alert ('salutations!');
}
and if I had no more code after the previous code, you would never see an alert popup. It would only be invoked when called/invoked after it's declaration/iniciation (HENCE the term: "it's being called back" after it was created AKA callback). However, if I included a trailing () after the callback function, it would then cause the function to actually execute during the declaration and initiation of function salutations.
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