I learned promises with jQuery and then didn't do much programming for a couple of years. Now I want to do some stuff using native ES6 promises.
Promises bent my head a little back then. Now with both being quite rusty on top of that and there being minor and major differences between jQuery promises, other promise libraries, and the new native JS promises, my head gets even more bent when I try to get this stuff working.
It seems like jQuery.when() and Promise.all() do the same thing, but are there some important differences we should keep in mind?
Promise.all() takes Array of Promises or plain JS objects as argument so you need to access results by index.
jQuery.when() takes multiple arguments which are plain JS objects or jQuery Deferred, so you can access your result by variable name.
Related
I've been thin lately about async/await lately and its case is similar to references.
In javascript there're no pointers, derefecence operators etc. that exist in low-level languages which makes javascript look simpler because it pretends that a variable stores a value for an object while in truth it stores reference to an object and magically resolves it to the object when it notices you actually want to get the data. So it looks as if the variable stored the object itself.
Pretty same situation can be observed with promises: when you have a promise stored in some variable, you actually don't care about the promise itself - you care about its value.
AFAIK there are no pointers in javascript because they were confusing and could be abstracted away so they were. Same goes for promises.
Instead of doing
const data = await fetch("endpoint");
you could be doing
const data = fetch("endpoint");
because javascript would figure out that what you want is the data returned by the fetch. Promises and async/await actually might become language's internal implementation detail.
Will it be possible (meaning can it be implemented in javascript)?
Is there a language that already does this?
Would you want this to land in javasrcipt?
It's extremely unlikely that javascript would support this pattern. It's current approach to async code is so deep, that having 'explicit await' everywhere would really make javascript no longer javascript. I do think it might be possible to come up with a language that compiles down to javascript.
If you're looking for a language that does do this, take a look at Go. It's a much saner model for asynchronous programming because it was considered from the start. In javascript, promises and async/await were tacked on much later.
9 times out of 10 you will want to 'await' a asynchronous function, so in go every function is 'awaited'. If you don't want to 'await' a function, you call the function like this:
go foo()
So comparing Go and Javascript, the go and await keywords are very similar, but used for opposite cases.
In go, the async keyword in front of functions is also not needed.
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 played with promises a few times a few years ago using either jQuery or Q. I'm now quite rusty and want to learn and use the new native ES6 promises.
I seem to remember one neat concept where you can "wait" on something and not care whether it's a plain object or a promise. If it's a promise the callback is called when it asynchronously completes, if it's anything else the callback is called immediately - maybe the next tick.
But I can't recall how this is done. I'm not sure if it has a name so it's proving difficult to Google for. I'm not sure if it's a standard feature across all JS promise implementations, or if it was just something only jQuery had.
What is this called? Can I still do this with native promises? Where can I read up on it?
Both jQuery's $.when() and ES6's Promise.all() exhibit the behaviour you refer to. Provide a promise and the function waits for the promise to resolve, but for any other value it returns immediately.
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