I've been reading a lot about the new jQuery.Deferred object. One thing that'd be really useful would be to be able to convert an existing object into a deferred one, then you'd get 100% flexibility about where you get your data from.
I'm thinking something along the lines of
$.makeDeferred({property: "data"}) // returns an object with .promise() method, in resolved state, and that passes the original object as data/context to any callback function
Does anyone know if this method already exists, or how to go about creating one?
You shouldn't need to wrap your object to get this effect, since most methods that are passed promises as parameters will treat a plain object as an already-resolved promise.
That said, if you really want this, try this:
(function($) {
$.makeDeferred = function() {
var d = $.Deferred();
d.resolve(arguments);
return d.promise();
};
))(jQuery);
This would at least allow you to also handle the case where you want to call a method of the promise, e.g. my_promise.done(), as opposed to passing the promise, i.e. $.when(my_promise).
[untested, may not work, E&OE, etc.]
EDIT
Actually, I thnk all you have to do is wrap your plain-old-data in $.when:
$.when({property: "data"})
Related
.
I want to get the[items] Array object separately.
My doubt is that the <value> object generated from the function return and due to <value> object it is not indexing properly.
I tried these approaches:
views.value.items not working.
views[0][items] not working.
views seems to be a Promise, that wraps the actual value you want. So you need to call the .then() method on it and provide a callback that can use the value that is inside the Promise. Or if you are in an async function, use await.
I would recommend to read at least the two following pages, that describe how to use promises in the two mentioned ways:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await
As I understand views and value is an object. If so, you can use views.value.items[0]
It is better to check value type with console.log(typeof views)
Within my Node.JS application I have written a function (findByReference) that goes to a database and asynchronously yields a fetched database row. I have written this function using Promises. Additionally, I have written an implementation of the Maybe monad and want my findByReference function to yield an instance of Maybe.
My code looks like the below:
findByReference(r)
.then(raw => raw ? Just(raw) : Nothing())
.then(row => {
(row instanceof Maybe) === true;
});
Without going into what Just and Nothing mean, the implication of this (because of how I've written Maybe) is that the row variable in the above code has a function on it called "then". To cut a long story short, it appears that Javascript is getting confused and is for some reason automatically calling MY "then" and instead of passing the Maybe is actually passing to the callback whatever MY "then" returns as the value of row. This is obviously leading to all manner of weird behaviour. If I simply remove the "then" function from my object then it all works as expected.
I am aware that if a Promise.then returns another Promise, then execution will pause until that promise is resolved. I have been unable to find any official documentation to back this up, but is it the case that this decision is simply based on the existence of a "then" function (the closest I have found is this https://developers.google.com/web/fundamentals/primers/promises which refers to the return value as "something Promise-like"). If this is the case, it would be my understanding that "then" as a function name is basically a reserved word in Javascript? I have seen other implementations of Maybe (such as this one https://www.npmjs.com/package/data.maybe) that use the word "chain" for a similar thing - I wondered if this is why?
Can anyone shed any light on if my deduction here is correct and if so is there any workaround I can use other than renaming my function?
FYI the only other SO question I've found that touches this problem is this one - Resolve promise with an object with a "then" function - but since that is angular-specific I don't believe this is a duplication.
Thanks in advance!
...the row variable in the above code has a function on it called "then". To cut a long story short, it appears that Javascript is getting confused and is for some reason automatically calling MY "then"...
It's not confused. :-) This is the definition of how promises work. JavaScript's promises work according to the Promises/A+ specification, which uses this terminology:
1.1 “promise” is an object or function with a then method whose behavior conforms to this specification.
1.2 “thenable” is an object or function that defines a then method.
If you have an object passing through a promise chain that's a thenable but not a promise, it's incompatible with promises.
So yes, in a sense, the then property of objects passing through promise chains is "reserved" by the Promises/A+ spec. You'll need to wrap your raw value in an object that doesn't have a then (and then unwrap it later). Or if you can, rename then in your design to remove the conflict.
I have one function that runs asynchronously, such as querying records from a database. The remaining code depends on the result, but runs synchronously. I am struggling to understand a good way to deal with this and would like to know the best practise?
Imagine the following code:
var usersDataPromise = getUsersDataFromDB();
var usersAgeArray = usersDataPromise.then(extractAges);
var averageAge = calculateAverageAge(usersAgeArray);
here, getUsersDataFromDB() runs synchronously and returns a promise. When the promise resolves, it runs extractAges(), a function that simply takes some of that data and returns an array. This function is sync. I want to pass that on to calculateAverageAge(), but this is where it breaks: calculateAverageAge does not wait for getUsersFromDB() to finish, and simply starts as soon as it can (usersAgeArray will be undefined).
What I tried:
I can make extractAges() return a promise instead of an array, and make calculateAverageAge wait with .then, by doing:
var usersDataPromise = getUsersDataFromDB();
var usersAgeArrayPromise = usersDataPromise.then(extractAges);
var averageAge = usersAgeArrayPromise.then(calculateAverageAge);
However, it feels as if I made the code needlessly complicated: I made extractAges() return a promise even though it runs asynchronously, not synchronously.
I realize I could have called calculateAverageAge() at the end of the extractAges function, but I'm trying to learn how to keep the code clean, and this feels as if I'm introducing side effects to a function that should only be extracting an array. Now the function description seems not fully accurate: it extracts an array but also calls on the next function.
I hope I've made this clear, I'm having trouble wrapping my head around it. What is the best way to deal with this? Thanks!
I can make extractAges() return a promise instead of an array
There's no reason to do that. Only because you are using a function in a then callback, it doesn't need to return promises.
and make calculateAverageAge wait with .then
Yes, you need to use then anyway, because the array is produced asynchronously and usersDataPromise.then(extractAges) always returns a promise. There's no alternative.
var averageAgePromise = getUsersDataFromDB().then(extractAges).then(calculateAverageAge);
I'm trying to understand the format of the Javascript functions that jQuery, among other people, use.
For instance jQuery(arg).hide() or $("#obj").hide
I'd like to write similar format functions but I don't understand how.
I know how to write
function myFunc(args) {
}
but I don't understand the second part ie the .hide()
is that a function within a function?
thanks for any help
It's called method chaining. The way to achieve this is for your first function to return an object, so the second function can be called as a method on that object.
The standard way to do this style of programming is to always return the same type of object, so for example, jQuery always returns a jQuery object representing a collection of HTML nodes. If one of the calls modifies the collection then the next call will be on that collection. That's how you can do something like $('#myid').parent().hide();. $('#myid') returns a jQuery object representing the #myid element and .parent() returns a jQuery object representing the parent element of #myid. .hide() returns the same object, so you could then call another method on the same object if you wanted.
This is called method chaining. I highly recommend picking up Crockford's "JavaScript: The Good Parts". This is a very quick read but wonderfully explains OOP in JavaScript and identifies good versus bad language features. Highly recommend it.
As Skilldrick pointed out, this is called method chaining.
The most straightforward example for this is an object that returns itself when you call any of its methods:
var world = {
'hello': function() {
alert('Hello');
return this;
},
'goodbye': function() {
alert('Goodbye');
return this;
}
};
world.hello().goodbye();
This is identical to world.hello(); world.goodbye();.
jQuery does a little more than that. Calling the jQuery or $ function on a valid selector string will return a jQuery object representing the matched elements (it's not actually an array, though you could think of it as one). Most of its methods will return the object itself after modifying the object (e.g. $("a").css({...}) will apply changes to the styling of the matched elements and then return the set of matched elements again).
But some jQuery methods allow modifying the set you're working with (e.g. $("a").parent() will return a jQuery object representing the parents of the matched elements). That is, they don't return the same object, but an object that behaves identically.
You have to be careful if you decide to use this style, though, as the flow will break if you need a method that has a return value of its own (e.g. if you want calculations or getter methods). This can be avoided by passing a callback function to the method, but the resulting coding style may be terribly convoluted.
In jQuery plugins, every time we return an object of jQuery, like
$.fn.Myplugin = function() {
return this.each(function() { //do some stuff });
});
My doubt is, why do we actually return an object of jQuery and where are we going to use this returned object
Though I don't return any jQuery object in my function(plugin), I still get the same result just as in returning an object
someone please explain my doubt,
Thanks for sparing your time, Have a Good Day !
The jQuery object is returned so we can do method chaining:
$('#somelement').doSomething().doAnotherThing().doOneMoreThing();
If you don't return it from one of your plugin methods, there's no more jQuery object to work with so subsequent calls will result in an error.
All jQuery methods return you jQuery Object so that the set of results returned can further be used to perform other operations this is also called chaining. This is done for tersness in the code. Its easy to code (atleast for me) and prevents me writing big loops.