I am currently attempting to learn the AngularJS framework and I keep hearing about something called "promise". I have researched a little about it, although I cannot seem to find a thorough explanation to how and when to use "promises".
Can anyone please explain and provide a solution between using a promise, and not using a promise. What is the advantage of using a promise over not using one?
All answer are appreciated.
Thanks.
promises implementation basically provides an interface which define at least one method 'when' that return therefore, a "Promise", thus a result from an async operation.
Advantages are better code readability (and production as well), better reuse of the results without incurring on the scaring "callbacks hell", chainabilty, etc...
A simple scenario with jQuery:
without promises
$.ajax({
url: someurl,
success: function(data)
{
//do something with data
}
});
with promises
var p = $.ajax({ url: someurl });
$.when(p).then(function(data)
{
//do something with data
});
However, a better explanation: http://wiki.commonjs.org/wiki/Promises/A
The official documentation says that
The promise api allows for composition that is very hard
to do with the traditional callback (CPS ) approach. For more on this
please see the Q documentation especially the section on serial or
parallel joining of promises.
http://docs.angularjs.org/api/ng/service/$q
I think the easiest explanation could be that it's a much better and cleaner way to do a serial or very complex callbacks than the traditional way.
This is the link you can read more about the benefit of using promise:
promises specification
Related
Why should I use an HTTP observable method like this:
this.http.get("MyURL")
.subscribe(
(_url: any) => {
//TODO My job
},
(error: any) => {
//TODO My job
},
() => {
//TODO My job
});
Instead of use an AJAX method like this:
$.ajax({
url: "MyURL",
success: function (result) {
//TODO My job
},
error: function () {
//TODO My job
}
});
I mean, what are the benefits and harms?
Why would you use an external library to do something angular is already capable of? Why would you actually use jQuery at all in combination with angular?
I think a better title for your question would have been, why use observables at all. I have had the same question when I started with angular, but after working with angular for over a year and having worked a lot with observables and rxjs over that period of time I have learned the following.
1- You cannot cancel promises
Lets say somebody goes to screen A, and you fetch some data like so.
fetch(/** some end point */)
.then(res => res.json())
.then(() => {
// Handle the request here
});
And by the time you are able to handle the request, the user leaves screen A. In most cases that is not a big deal, but because you want to do things the best way possible you would preferably cancel the handling of the request. With native promises, that's simply impossible. Read this article for great explantion on this
With observables, this becomes trivial. You can unsubscribe from an observable and that will ensure no unnecessary code is executed.
Pro tip: In angular you would do this in the ngOnDestroy life cycle of a component.
2 - Native promises have 2 methods, rxjs has many many more.
If you are using the native promises implementation, the only things you can do are then and catch (on a promise instance). This might seem more than enough, but with rxjs you can do many many more things.
Example
Lets say your /article/:id end point sometimes returns empty values because there is no article found. In promises your code will look something like this.
fetch('/article/5')
.then( res => res.json())
.then( res => {
if ( res !== undefined) {
// do something!
}
});
In rxjs this looks much cleaner, in the case of wanting to only do something with the data if its there. This might not seem as a big improvement, but in production you will find yourself wanting to do much much more than filtering out undefined values.
this.http.get("MyURL")
// p.s this line of code might not be needed depending on ur
// angular version
.map( res => res.json())
.filter( res => res !== undefined)
.subscribe(res => {
// Do something!
});
My advice for you would be to use toPromise wherever you are doing something simple, and to gradually use more and more rxjs operators once you need them. map, filter and takeUntil would be a good starting point.
I could go on showing you things you can do with rxjs that are hard to implement with promises, but there are lots of articles out there that do a better job than me explaining that.
TLDR
You can write cleaner asynchronous code and do more things with less code.
Please read the below link for better information :
https://angular-2-training-book.rangle.io/handout/observables/observables_vs_promises.html
What it seems like it is used majorly because Observables can define both the setup and teardown aspects of asynchronous behavior.
Fundamentally, they're the same thing. It's really just the implementation and usage that differ, so it becomes a matter of preference really.
Observables (which generally refer to the "RxJS" library, though not always) generally have a subscribe() method which lets them listen for changes, and have hooks for onNext() (something happened), onError() (something went wrong), and onComplete() (all done).
jQuery's AJAX syntax is a more "classic" callback structure, where you call the function and provide it with callbacks directly. It also has another syntax which allows you to add them as subsequent functions (.done() and the like).
When talking about JavaScript specifically though, nowadays I would argue that the Promise syntax is the most popular, as it is standardized in ECMAScript 6 and is natively supported by most browsers nowadays. fetch() is a native implementation of doing AJAX requests with Promise syntax.
At the end of the day, neither is particular better or stronger at the end of the day, and it really just boils down to personal preferences and past experience (for example, Observables are popular with developers who have Java experience, since Observables are used pretty frequently in Java).
Out of the three, only the Promise one has any real advantage, which is that it is natively supported by modern browsers (whereas the other two require a third-party library). But if you're already using a third-party library for something else, that's not a huge benefit.
Background: I have been tasked to help resolve an issue with the following error:
'Promise' is undefined'
Which is part of our sessionsmodel.js script:
return Promise.all(promises);
promises is an array of actions that need to happen and if any fail it is rejected.
Question: Based on my research IE does not support Promise so is there a work around that can be applied to this return value that will accomplish the same thing?
Since you are using Backbone, the promises are probably jQuery promises. You could use jQuery .when function to do the same as Promise.all:
return $.when.apply($, promises);
For most other simple situations where you call functions like save and fetch, you could avoid promises completely by using the provided callbacks:
model.save({
context: this,
success: this.onModelSuccess
});
There's no need to use another library because Backbone uses jQuery already (by default), unless you don't like jQuery deferred or that you're using something else in place of jQuery.
ES6 Promise spec was implemented by "good" libraries like Q, When, RSVP, Bluebird, Lie and more...
If you want to learn more on Promises, check this link:
Promises
I recommend you use a polyfill.
I have a load() function, Inside that I want to call a function say download(), which download a xml file. Once download is completed , I have to call a function say parseXML() which parses the downloaded xml file. Once the parsing is completed, I have to call another function say processParsedXMLFile(). Can you please guide me how can I achieve this in the simplest possible way ?
You can use callbacks
load(params , function(){
download(params, function(){
parseXML(params, function(){
processParsedXMLFile(params, function(){
...
})
})
})
})
Two common approaches exist for asynchronous code in JavaScript - callbacks and promises.
There are many posts on SO discussing callback and Javascript callback after json parse shows good example with detailed explanation.
For promises: http://wiki.commonjs.org/wiki/Promises/A and https://www.promisejs.org/ are good starting place to read about Promises which are more common now to write asynchronous code in JavaScript.
Depending on where you run you script you may need to include packages/libraries to have support for promises:
NodeJS - install corresponding package ("promise", "q",...)
WinJS -promises are natively supported. Info - WinJS.Promise and guide Asynchronous programming in JavaScript, there are also many question on SO covering different aspects like WinJS, return a promise from a function which may or may not be async
For regular browsers using jQuery's implementation is common practice -[]jQuery.promise](http://api.jquery.com/promise/). With broader availability of ES6 compatible browsers you will not need additional libraries - MDM Promise - ES6
With promises would look like following (assuming each of the calls returns promise that is fulfilled when operation finishes):
download()
.then(function(data){/* parse XML here */})
.then(function(data){/* process parsed XML*/ });
I recently started working with NodeJS and MongoDB(using Monk). This is when I came across the term "callback hell". In my code I was exactly doing the same thing. For an example-
DBCall(d1, function(e, docs){
if(docs.length!=0)
DBCall(d2, function(e, docs1){
if(docs1.length!=0)
DBCall(d3, function(e, docs2){
//doing something with docs,docs1,docs2
})
})
})
This is when I started reading on "promises", and I came across this article - https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/
Since I needed both docs and docs1 inside the third callback so I used nested promises.
DBCall(d1)
.then(function(docs){
if(docs.length!=0)
return DBCall(d2)
.then(function(docs1){
if(docs1.length!=0)
return DBCall(d3)
.then(function(docs2){
//doing something with docs,docs1,docs2
})
})
})
From the above code snippet I have the following questions(/doubts) :
Apart from making the code more readable, does promises have performance benefits?
Nesting promises and callback hell looks similar to me. Is there actually any difference?
I am new to this concept of promises. Any help is appreciated.
Apart from making the code more readable, does promises have performance benefits?
Probably not.
Nesting promises and callback hell looks similar to me. Is there actually any difference?
Promises don't automatically prevent callback hell. But because they are more flexible than "simple" callbacks, they can be composed in different ways, which makes it easier to avoid callback hell.
Since I needed both docs and docs1 inside the third callback so I used nested promises.
Sometimes nested promises are unavoidable. However, there is no need to nest them if they don't have to be executed sequentially. You could execute them in parallel:
Promise.all([
DBCall(d1),
DBCall(d2),
DBCall(d3)
]).then(function(docs) {
// docs is an array: [docs, docs1, docs2]
});
Basically the purpose of Promises is to allow for functional composition and error handling, in a way that reads in a synchronous nature. Promises allow you to read code in a linear (maybe wrong term) or synchronous fasion.
This is sort of a broad question but take a look through these suggested links.
https://promise-nuggets.github.io/
https://blog.domenic.me/youre-missing-the-point-of-promises/
also this link
Edit:
After reading your updates, what you're essentially asking for is to join the promises (I think)
This SO Post gives some good info. Some of the better libraries have utility functions to help with this.
For example, if using bluebird take a look at the join function
I'm working for the first time with async programming, specifically with promises in Javascript and I'm really confused with it. I'm still thinking like we do in C, PHP, C# and so on where for each step the next one can be sure of it's completion. This is easy to work, because if we have a code like that (in C# for example)
IEnumerable<Page> pages = pagesRepository.getAll();
we can be sure in the next line that all pages are available for us to use in the pages object. This makes life easier, because we can already do work with that data properly.
Now, in JS with promises we would have something like
var pages = dataService.getPages();
and this would not return the data, but just a promise which is very different. Of course we can add a callback with then but I'm getting confused, because somewhere else in my code I might need to reference this variable, and I cannot be sure when the callback will be called.
So how do we think when we deal with those things? Is there some tutorial or some videos out there that show in detail how to work with async programming with promises in JS?
Of course we can add a callback with then but I'm getting confused, because somewhere else in my code I might need to reference this variable, and I cannot be sure when the callback will be called.
You don't need to.
The "somewhere else code" will use .then() and yield a new promise for its result, relying on the pages promise. You can easily map the results, or chain other asynchronous tasks. Whenever you need to know about the timing of callbacks because of multiple dependencies, you should use your library's methods for composing promises, like all().
So how do we think when we deal with those things?
Think functional!
Every task in your program should explicitly and only depend on its inputs. A function should try to only use its arguments, not any global variables that contain state.
Is there some tutorial or some videos out there that show in detail how to work with async programming with promises in JS?
General Promise Resources in the wiki of the Q library is a very good start.
The simple answer here is that promises are similar to Task asynchronous programming in C#.
However instead of being able to use the 'await' operator, the 'then' function on a promise is analogous to using 'ContinueWith' to chain Tasks in C#.
Callbacks can get complicated to use across scopes, especially with extensive use of nested anonymous functions, so please give promises a go