I've been looking into the google closure library for ajax calls, and I've gone through an example that looks like:
goog.events.listen(request, "complete", function(){
if (request.isSuccess()) {
// do something cool
} else {
// display an apologize message
}
});
As opposed to a jquery example that looks something like:
$.ajax({url: url, success: function () { }, error: function () { }});
I've been seeing google closure popup a lot more, but what would be the advantage or disadvantage in this case? The jquery library calls just seem a lot simpler for ajax related calls like this one.
Your Closure sample is incomplete. I assume just before your sample you created an XhrIo instance and called send() on it.
If you want a simpler Closure equivalent to the jQuery sample you posted you can use the static XhrIo.send(). It would look something like this:
goog.net.XhrIo.send(
url,
function(event) {
var xhr = event.target;
if (xhr.isSuccess()) {
// do something cool
} else {
// display an apologize message
}
});
That's admittedly clunkier than the jQuery version. In general, Closure is designed with object-oriented programming in mind (in stark contrast to jQuery which is mostly static functions). This may suit you or not, depending on whether you prefer to write your JS code in an object-oriented way.
In this particular case you might get a small advantage out of Closure if you create an XhrIo object that you reuse for multiple requests (e.g., you can setTimeoutInterval() on it to be used for all requests). If you care about memory, Closure may also give you more explicit control over garbage collection.
Related
I realise this is more of a general question, but I've read through similar answers on here but I can't find more of an overview. I'm new to callbacks and I'm trying to understand when they should be used.
The MDN web docs has this example;
function greeting(name) {
alert('Hello ' + name);
}
function processUserInput(callback) {
var name = prompt('Please enter your name.');
callback(name);
}
processUserInput(greeting);
However I'm struggling to see how this is more beneficial than the following, where I'm not passing the greeting function as a parameter?
function greeting(name) {
alert('Hello ' + name);
}
function processUserInput() {
var name = prompt('Please enter your name.');
greeting(name);
}
processUserInput();
As Javascript is async, sometimes it is difficult to handle response from non-blocking functions, for ex. if you are making an ajax call then it'll be executed asynchronously and results will be returned sometime later, by that time the main execution flow will pass the ajax code and starts executing following statements, in that case, its very difficult to catch the response to process further.
To handle those cases, callbacks comes into picture where you pass a function as the parameter to the ajax function and once the response is returned then call the callback by passing response data as a parameter to process further.
more info here http://callbackhell.com/
In simple terms you can say a callback is a way of asking a question (or requesting a task) in advance, i.e. when you're done with this do this (usually with the result). The whole point is to set aside functions that are to be done later, usually because you don't have the required inputs to do them now.
The 2 main differences between your implementation and the MDN one is that yours is harder to maintain and harder to reason about hence test.
1. Maintanance / Reusability
Imagine you're a few thousand lines of code into a code base then you're required to change what processUserInput() does. Its much easier to change or write a new callback function instead of changing the function processUserInput(). This would be evident if processUserInput was a bit more complicated. This also means the MDN one is much more useful in various scenarios unlike your implementation. You can reuse it in different situations like saying good bye, capitalizing names etc simply by writing different callbacks to plug into processUserInput().
2. Testing / Easier to reason about
The MDN implementation is much more easier to understand. Its easier to assume that the function processUserInput(greeting) will probably return a greeting than it is to assume what processUserInput() does. This makes it easier to test because you can always be sure the MDN implementation will always return the same output given an input.
Callbacks can be extremely useful depending on the circumstances; for example, when working with JavaScript for Google Chrome browser extension development, a callback can be used for intercepring web requests once it has been setup.
The purpose of a callback in general is to have the callback routine executed upon a trigger - the trigger being an event of some kind. Usually, functionality follows an interface of chained APIs. By implementing callback support, you can redirect execution flow during a stage of an operation. Callbacks are especially useful to third-party developers when dealing with someone elses library depending on what they are trying to do. Think of them like a notification system.
Functions in general taking in parameters is useful for flexibility and maintenance. If you use different functions for different things, the functions can be simply re-used over and over again to provide different functionality - whilst still preventing bloating the source code with more-or-less the same code over and over again. At the same time, if you use functions to your own library and a bug shows up, you can simply patch it for the one function and then it will be solved.
In your example, your passing a callback routine to the function you're calling - the function you're calling will call the callback function and pass the correct parameters. This is flexible because it allows you to have a callback routine called for printing the contents of the variable, and another for calculating the length of the string passed in, or another for logging it somewhere, etc. It allows you to re-use the function you setup, and have a different function called with the correct parameters without re-making the original function.
This example is not appropriate for understanding callbacks
In simple Language callbacks functions are used when we have to do some stuff after or in response of some other event or function or expression.
i.e when the parent function completes its execution then callback gets executed.
simple Example
function hungerStatus(status,cb){
return cb(status)
}
function whatToDo(status){
return status ? "order Pizza" : "lets play"
}
hungerStatus(false,whatToDo)
Another example
// global variable
var allUserData = [];
// generic logStuff function that prints to console
function logStuff (userData) {
if ( typeof userData === "string")
{
console.log(userData);
}
else if ( typeof userData === "object")
{
for (var item in userData) {
console.log(item + ": " + userData[item]);
}
}
}
// A function that takes two parameters, the last one a callback function
function getInput (options, callback) {
allUserData.push (options);
callback (options);
}
// When we call the getInput function, we pass logStuff as a parameter.
// So logStuff will be the function that will called back (or executed) inside the getInput function
getInput ({name:"Rich", speciality:"JavaScript"}, logStuff);
refer callback exaplanation
Reworded:
A common pattern is to pass callback functions, such as with Mongoose's save (just for example and simplified - no error handling):
someMethod(req:Request, res:Response){
document.save( function(err){ res.status(200).send({message: 'all good'})});
}
I'd like to externalize the callback. You can do this this way:
var respond = function(err:any, res:Response){
res.status(200).send({message: 'all good'});
}
someMethod(req:Request, res:Response){
document.save( function(err){ respond(err, res)});
}
...but ideally I'd like to do this by just passing a function like respond without having to create a call back function to enclose respond. I wanted to know if this is possible. Since the anonymous function has access to res, I thought there might be some way to gain access to res in a function defined externally. It appears there is not a way to do this so I'll live with wrapping it.
My original question was trying to isolate the specific issue I was interested in - which is to gain access to the caller's variables implicitly. Doesn't seem like that is possible. Fair enough.
Original Question:
I'd like to externalize a bit of code I use frequently and I'm having trouble understanding closure in the context of a Typescript method. Take a look:
var test = function(){
console.log("Testing external: "+JSON.stringify(this.req.body));
}
class Handler {
static post(req: Request, res: Response){
(function(){
console.log("TESTING anon: "+JSON.stringify(req.body));
}) ();
test();
}
}
Besides the fact that this does nothing useful, in this bit of code, the inline anonymous function has access to the req object, but the test() function does not. this in test is undefined. Removing this to match the inline function doesn't help.
I believe if I were to bind on this for the call I'd just end up with a reference to the Handler class when I really want to bind on the post method.
My motivation for doing this is that I want to make a function that can be passed as a callback to a bunch of different request handlers. When I write the functions inline it all works, but when I externalize it I can't get a closure over the variables in the enclosing method. I've read "You Don't Know JS: this & Object Prototypes", and in pure Javascript I can manage to make these sorts of things work but I'm obviously doing something wrong here (it may not be Typescript related, maybe I'm just messing it up).
So bottomline - is there a way I can externalize the handler and get access to the method variables as if I were writing it inline? I could just create an inline anonymous function as the callback that calls the external function with all the variables I need, but I want to really understand what is happening here.
This is not an answer, but will hopefully give me enough feedback to give you one because its not at all clear what you're actually trying to accomplish here and whether or not you actually understand what the terms mean is an open question since you use them correctly one minute and sketchily the next.
var test = function(){
console.log("Testing external: " + JSON.stringify(this.req.body));
}
In strict mode this will throw an error, in sloppy it will try to access the req property of the global object which is not likely what you want.
(function(){
console.log("TESTING anon: "+JSON.stringify(req.body));
}) ();
The IFFE wrapper is completely unnecessary, it literally adds nothing to the party. So why include it?
static post(req: Request, res: Response){
console.log("TESTING anon: "+JSON.stringify(req.body));
test(); // is this the spot where you are 'in-lining?'
}
What I think you want is this:
var test = function(reqBody) {
console.log("Testing external: " + JSON.stringify(reqBody));
};
class Handler {
static post(req: Request, res: Response) {
test(req.body);
}
}
I'm writing a basic wrapper for the Webkit Storage API (the new version of this API) for me to use. My current problem with it is the queryUsageAndQuota() function.
My wrapper around that particular function originally looked like this:
self.pers.getQuota = function() {
self.pers.queryUsageAndQuota(function(usage,quota) {
return quota;
});
}
// self is a reference to the top level of this 'wrapper'
Hence, I would have called var quota = self.pers.getQuota(); and had the quota returned.
After that failed, I had a look at this question and changed it so I used a user-defined callback instead. Now the function is this:
self.pers.getQuota = function(callback) {
self.pers.queryUsageAndQuota(function(usage,quota) {
callback.call(quota);
});
}
However, executing this line:
self.pers.getQuota(function(quota) {
console.log(quota);
});
shows undefined in the log. I can't figure out why, because when I execute the underlying function navigator.webkitPersistentStorage.queryUsageAndQuota(), I get the right number out of it.
.call doesn't work like you think it does. Instead do callback.call(null, quota).
The actual signature for both Function.prototype.call (and similarly for apply) is
Function.prototype.call(valueOfThis, valueOfParam1, valueOfParam2, ...);
This is also why I often say that the this keyword in javascript is stupid and you should avoid using it. It simply is another parameter like all the others, You just don't get to specify a name for it. It's a vestige of javascript's creation when Netscape mandated that this Scheme-based language look like Java.
Incidentally, you could use the third way of invoking methods here. Simply
callback(quota);
This however has the side effect of making javascript take a guess at what you want this to be (the global window object in this case). As long as you don't use this, the simple syntax works great.
If you actually really want to return a value rather than passing a callback look into javascript promises. I can't tell you which one to use without knowing what environment you in and what libraries you're using but jQuery has a good implementation in the Deferred object
Try
self.pers.getQuota = function(callback) {
self.pers.queryUsageAndQuota(function(usage,quota) {
callback(quota);
});
}
Or
self.pers.getQuota = function(callback) {
self.pers.queryUsageAndQuota(function(usage,quota) {
callback.call(/* an object as 'this'*/, quota);
});
}
Function.prototype.call()
Or
self.pers.getQuota = function(callback) {
self.pers.queryUsageAndQuota(function(usage,quota) {
callback.apply(/* an object as 'this'*/, [quota]);
});
}
Function.prototype.apply()
Is there any way to create an object that respond to any message? Suppose you have the following object:
function Dog();
Dog.prototype.speak(){
alert("woof woof");
}
var myDog = new Dog();
Then when you do myDog.speak() you will get an alert with "Woof woof". But what I want is when you call myDog.jump() (which is not defined in the class) you will get a default action like show the user an alert with "you are trying to excecute an inexistent method".
Do you know how can I do it?
Short answer: you can't.
Long answer: you could use __noSuchMethod__ but it's not standard and there are some plans to remove it, because Proxy can do the same, and more. Plus, it's a standard.
Therefore, you could use a Proxy to do that, but I would discourage to have all objects as proxies, because performance reasons.
Personally, I would just leave the language thrown it's own exception, that the developer can check in the error console.
There is no standards-based way to do this. The closest thing is this.
The closest you could get to this would be:
function execute(obj, message, args) {
if (obj[message] && typeof(message) === function) {
obj[message].call(obj, args);
} else {
obj[message] = function() {
//missing method functionality a la Ruby here
};
}
}
Others have already mentioned __noSuchMethod__ and Proxy so I'll refrain from going into further detail on those.
Instead, I wanted to highlight another technique that may be able to do what you want. Please be aware that this is a ugly hack, I can't encourage it's usage and it may not even work in all of your targets. With those caveats in mind, I present you with window.onerror:
window.onerror = function(err) {
if (/has no method/.test(err)) {
console.log('oh my: ' + err) // This is where you'd call your callback
return true
}
return false
}
;(function() {
this.foo() // will be caught by window.onerror
})()
This – at least in my very limited testing – catches TypeErrors (in Chrome at least, mileage may vary) that signified that the method could not be found. Here are some of the reasons why you should not do this:
window.onerror can only have one handler; if your handler is overwritten this won't work
It catches TypeErrors globally, not just for a specific object; i.e. lot's of false positives
It'll make it fun to debug for anyone coming in not knowing where to find this handler
It tightly couples any bit of code you have that relies on this behavior (bad, bad, bad!)
I don't think I can stress enough how much you really shouldn't be thinking of hacking this in. Use Proxy if you can, admit defeat if you can't.
I'm debugging an app that uses .NET's scriptmanager.
It may be a glitch in firebug, but when I read through the code there are a lot of lines like the following:
// anonymous functions not attached as handlers and not called immediately
function () {
//code
}
// named functions added as methods
myObj = {
myMethod: function myFunctionName() {
//code
}
}
Are these lines valid and, if so, what do they do and what possible reason would there be for coding like this (and I won't accept "It's microsoft - what d'you expect" as an answer)?
This might be worth a read: How does an anonymous function in JavaScript work?
They are there because some busy programmer was intending to do something and ran out of time, but left the stub as a reminder of work to be done. They do nothing as of yet.
or to watermark the code for checks that are done elsewhere in the logic
or simply put there to obfuscate...