Resolve jQuery deferred with a promise - javascript

According to the promise resolution procedure of Promises/A+ specification it is
possible to resolve a deferred with a promise.
For example in Q library you just do:
deferred.resolve(promise);
Whether the implementation of promises bundled with jQuery supports this? I tried the same with jQuery and it treats promise just as an immediate value.

Whether the implementation of promises bundled with jQuery supports this?
No. jQuery is not Promise/A+-compliant.
However, notice that the spec is only about then and the promises returned by it, it does not mention Deferreds or how to resolve them. jQuery does indeed support assimilation of promises returned from a .then() callback (since V1.8, at least).

Related

Difference between $q constructor and promise interface

What is a promise interface in angular JS?
Also what is a $q constructor?
When are these used and what is the difference between them?
I referred few sources but couldn't get the difference. Any pointers?
here are the definition for promise and $q,
A promise is a special type of Object that we can either use, or construct ourselves to handle asynchronous tasks. We deem them promises because we are “promised” a result at a future point in time. For example an HTTP call could complete in 200ms or 400ms, a promise will execute when resolved.
A promise has three states, pending, resolved or rejected. Using $q in Angular, we can construct our own promises, however let’s look at the ECMAScript2015 Promise Object first to get familiar on how to create one.
you can get more knowledge from this site: https://toddmotto.com/promises-angular-q

Promise.all() work around for IE 11 with Backbone

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.

"Waiting" on either a promise or regular object using native(ES6) JavaScript promises

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.

return deferred or deferred.promise() [duplicate]

What are the differences between Deferreds, Promises and Futures?
Is there a generally approved theory behind all these three?
These answers, including the selected answer, are good for introducing promises
conceptually, but lacking in specifics of what exactly the differences are in
the terminology that arises when using libraries implementing them (and there
are important differences).
Since it is still an evolving spec, the answer currently comes from attempting to survey both references (like wikipedia) and implementations (like jQuery):
Deferred: Never described in popular references,
1
2
3
4
but commonly used by implementations as the arbiter of promise resolution (implementing resolve and reject).
5
6
7
Sometimes deferreds are also promises (implementing then),
5
6
other times it's seen as more pure to have the Deferred only
capable of resolution, and forcing the user to access the promise for
using then.
7
Promise: The most all-encompasing word for the strategy under discussion.
A proxy object storing the result of a target function whose
synchronicity we would like to abstract, plus exposing a then function
accepting another target function and returning a new promise.
2
Example from CommonJS:
> asyncComputeTheAnswerToEverything()
.then(addTwo)
.then(printResult);
44
Always described in popular references, although never specified as to
whose responsibility resolution falls to.
1
2
3
4
Always present in popular implementations, and never given
resolution abilites.
5
6
7
Future: a seemingly deprecated term found in some popular references
1
and at least one popular implementation,
8
but seemingly being phased out of discussion in preference for the term
'promise'
3
and not always mentioned in popular introductions to the topic.
9
However, at least one library uses the term generically for abstracting
synchronicity and error handling, while not providing then functionality.
10
It's unclear if avoiding the term 'promise' was intentional, but probably a
good choice since promises are built around 'thenables.'
2
References
Wikipedia on Promises & Futures
Promises/A+ spec
DOM Standard on Promises
DOM Standard Promises Spec WIP
DOJO Toolkit Deferreds
jQuery Deferreds
Q
FutureJS
Functional Javascript section on Promises
Futures in AngularJS Integration Testing
Misc potentially confusing things
Difference between Promises/A and Promises/A+
(TL;DR, Promises/A+ mostly resolves ambiguities in Promises/A)
In light of apparent dislike for how I've attempted to answer the OP's question. The literal answer is, a promise is something shared w/ other objects, while a deferred should be kept private. Primarily, a deferred (which generally extends Promise) can resolve itself, while a promise might not be able to do so.
If you're interested in the minutiae, then examine Promises/A+.
So far as I'm aware, the overarching purpose is to improve clarity and loosen coupling through a standardized interface. See suggested reading from #jfriend00:
Rather than directly passing callbacks to functions, something which
can lead to tightly coupled interfaces, using promises allows one to
separate concerns for code that is synchronous or asynchronous.
Personally, I've found deferred especially useful when dealing with e.g. templates that are populated by asynchronous requests, loading scripts that have networks of dependencies, and providing user feedback to form data in a non-blocking manner.
Indeed, compare the pure callback form of doing something after loading CodeMirror in JS mode asynchronously (apologies, I've not used jQuery in a while):
/* assume getScript has signature like: function (path, callback, context)
and listens to onload && onreadystatechange */
$(function () {
getScript('path/to/CodeMirror', getJSMode);
// onreadystate is not reliable for callback args.
function getJSMode() {
getScript('path/to/CodeMirror/mode/javascript/javascript.js',
ourAwesomeScript);
};
function ourAwesomeScript() {
console.log("CodeMirror is awesome, but I'm too impatient.");
};
});
To the promises formulated version (again, apologies, I'm not up to date on jQuery):
/* Assume getScript returns a promise object */
$(function () {
$.when(
getScript('path/to/CodeMirror'),
getScript('path/to/CodeMirror/mode/javascript/javascript.js')
).then(function () {
console.log("CodeMirror is awesome, but I'm too impatient.");
});
});
Apologies for the semi-pseudo code, but I hope it makes the core idea somewhat clear. Basically, by returning a standardized promise, you can pass the promise around, thus allowing for more clear grouping.
What really made it all click for me was this presentation by Domenic Denicola.
In a github gist, he gave the description I like most, it's very concise:
The point of promises is to give us back functional composition and error bubbling in the async world.
In other word, promises are a way that lets us write asynchronous code that is almost as easy to write as if it was synchronous.
Consider this example, with promises:
getTweetsFor("domenic") // promise-returning async function
.then(function (tweets) {
var shortUrls = parseTweetsForUrls(tweets);
var mostRecentShortUrl = shortUrls[0];
return expandUrlUsingTwitterApi(mostRecentShortUrl); // promise-returning async function
})
.then(doHttpRequest) // promise-returning async function
.then(
function (responseBody) {
console.log("Most recent link text:", responseBody);
},
function (error) {
console.error("Error with the twitterverse:", error);
}
);
It works as if you were writing this synchronous code:
try {
var tweets = getTweetsFor("domenic"); // blocking
var shortUrls = parseTweetsForUrls(tweets);
var mostRecentShortUrl = shortUrls[0];
var responseBody = doHttpRequest(expandUrlUsingTwitterApi(mostRecentShortUrl)); // blocking x 2
console.log("Most recent link text:", responseBody);
} catch (error) {
console.error("Error with the twitterverse: ", error);
}
(If this still sounds complicated, watch that presentation!)
Regarding Deferred, it's a way to .resolve() or .reject() promises. In the Promises/B spec, it is called .defer(). In jQuery, it's $.Deferred().
Please note that, as far as I know, the Promise implementation in jQuery is broken (see that gist), at least as of jQuery 1.8.2.
It supposedly implements Promises/A thenables, but you don't get the correct error handling you should, in the sense that the whole "async try/catch" functionality won't work.
Which is a pity, because having a "try/catch" with async code is utterly cool.
If you are going to use Promises (you should try them out with your own code!), use Kris Kowal's Q. The jQuery version is just some callback aggregator for writing cleaner jQuery code, but misses the point.
Regarding Future, I have no idea, I haven't seen that in any API.
Edit: Domenic Denicola's youtube talk on Promises from #Farm's comment below.
A quote from Michael Jackson (yes, Michael Jackson) from the video:
I want you to burn this phrase in your mind:
A promise is an asynchronous value.
This is an excellent description: a promise is like a variable from the future - a first-class reference to something that, at some point, will exist (or happen).
A Promise represents a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers to an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of the final value, the asynchronous method returns a promise of having a value at some point in the future.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
The deferred.promise() method allows an asynchronous function to prevent other code from interfering with the progress or status of its internal request. The Promise exposes only the Deferred methods needed to attach additional handlers or determine the state (then, done, fail, always, pipe, progress, state and promise), but not ones that change the state (resolve, reject, notify, resolveWith, rejectWith, and notifyWith).
If target is provided, deferred.promise() will attach the methods onto it and then return this object rather than create a new one. This can be useful to attach the Promise behavior to an object that already exists.
If you are creating a Deferred, keep a reference to the Deferred so that it can be resolved or rejected at some point. Return only the Promise object via deferred.promise() so other code can register callbacks or inspect the current state.
Simply we can say that a Promise represents a value that is not yet known where as a Deferred represents work that is not yet finished.
A promise represents a value that is not yet known
A deferred represents work that is not yet finished
A promise is a placeholder for a result which is initially unknown while a deferred represents the computation that results in the value.
Reference
http://blog.mediumequalsmessage.com/promise-deferred-objects-in-javascript-pt1-theory-and-semantics

Mongoose promises documentation says queries are not promises?

From the docs (Mongoose v5.4.1, latest version):
Mongoose async operations, like .save() and queries, return
thenables.
This means that you can do things like MyModel.findOne({}).then()
second parapraph from the docs states:
Mongoose queries are not promises. They have a .then() function for co
and async/await as a convenience.
What Javascript MDN webpage states:
The then() method returns a Promise.
Does this mean that mongoose has another kind of implementation for async functions where they reserved the then keyword for the result of the async action?
In other words, they act like promises but are not JS promises?
From the documentation:
Mongoose queries are not promises. They have a .then() function for co
and async/await as a convenience. However, unlike promises, calling a
query's .then() can execute the query multiple times.
So unlike an actual promise, if you call then() multiple times on the query, you actually execute the query (or update) multiple times.
If you want an actual promise, call exec() on the query.
let promise = Test.findOne({}).exec();
All promises are thenables, but not all thenables are promises. To make things more complicated, not all promises are Promises (instances created by JavaScript's built-in Promise constructor).
JavaScript promises are an implementation of the Promises/A+ specification, which defines the terms like this:
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.
So Mongoose's queries are not promises, not even by that definition, since their then method is not compatible with the Promises/A+ spec. See JohnnyHK's answer for why they aren't compatible with the Promises/A+ spec (they run the query).
In other words, they act like promises but are not JS promises?
They only act a bit like promises. They are not promises. Their then is not implemented per the spec, it has side effects (running the query). If you want a true promise, see JohnnyHK's answer (e.g., use exec).
In general, if you have a thenable that's at least somewhat promise-like, you can get a proper promise for it by using Promise.resolve:
Promise.resolve(theThenable)
.then(/*...*/)
.catch(/*...*/)
.finally(/*...*/);
Promise.resolve will provide a true Promise instance that is resolved to the Mongoose thenable/promise: It will wait for that thenable/promise to settle and then settle the same way. That would work on a Mongoose query (provided you only do it once; exec is the better way with Mongoose queries).
They are "promise like", which means you can await them and call .then() and .catch() on them, however they are not instanceof Promise.

Categories

Resources