In the following code, the output clearly shows that rejected is within the created promise1 object. Yet when I look at MDN, there is no property indicating whether a promise is resolved or rejected. How does the program know whether a promise is accepted? Where is this information stored?
const promise1 = new Promise((resolve, reject) => {
throw 'Uh-oh!';
});
console.log(promise1); //Promise { <rejected> 'Uh-oh!' }
promise1.catch((error) => {
console.error(error);
});
There is no public API to check the Promise state, so there is no property that you could check.
Given the impossibility, you can try to do it on your own with any of these solutions:
https://ourcodeworld.com/articles/read/317/how-to-check-if-a-javascript-promise-has-been-fulfilled-rejected-or-resolved
https://github.com/nodejs/node/issues/40054#issuecomment-917641057
If I correctly get the question, you ask about the cases upon which JS itself rejects the promise. A promise is rejected when an error is returned from the callback function. In general case you (the programmer) define the conditions which mean success or error according to the code business. Based on what you need, you can either throw or reject the promise and this Q&A looks helpful.
But when a promise is gonna be used with a specific purpose, this behavior seems more clear, say when you use JS fetch api, there are solid situations in which the promise would be rejected.i.e. network disconnections or CORS errors. Here you can find a more detailed reply. These situations are those which are not biased towards any data transfer protocol such as HTTP.
Finally, here, you can find a pretty well explained pattern for designing your promise workflow.
Related
When we create a Promise(), the constructor expects two parameters: resolve and reject.
Can I create a Promise using only resolve?
let promise = new Promise((resolve) => {});
I've tried and it works. But, it is a good practice? The promise is expected to be resolved in all circumstances.
Yes, it's doable. If
you're sure the Promise will always resolve, or
there is no real way to detect if an error occurs (in which case a reject parameter wouldn't be used anyway)
then using only the resolve parameter is a reasonable possibility.
If there's any chance of an error - even an unexpected error - it'd be a good idea to use the reject parameter, though. Many errors are not expected, after all.
yes you can with
Promise.resolve(value);
refer https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve
This question already has answers here:
When is .then(success, fail) considered an antipattern for promises?
(7 answers)
Closed 4 years ago.
I have come across multiple applications where using catch is preferred over rejectHandler.
Eg:
Preferring
new Promise.then(resolveHandler).catch()
instead of
new Promise().then(resolveHandler, rejectHandler).catch()
Is there a particular reason for this??
I find
new Promise().then(resolveHandler, rejectHandler).catch()
to be more useful because
I can use rejectHandler to address designed/expected error scenario where Promise.reject is called.
I can use catch block to address unknown/unexpected programming/runtime errors that occur.
Does someone know any particular reason why rejectHandler is not used much?
P.S. I am aware of newer alternatives in ES6 but I just curious to know this.
Update: I KNOW HOW rejectHandler and catch works. The question is why do I see more people use only catch over both rejectHandler and catch? Is this a best practice or there is some advantage?
Update(Adding answer here): Found the answer I was looking for first hand.
The reason is not just because the error in reject is handled by catch it is mainly because of chaining. When we are chaining promise.then.then.then.then, having a resolve, reject pattern proves a bit tricky to chain it since you wouldn't want to implement a rejecthandler just to forward the rejectData up the chain. Using only promise/then/catch along with resolve/return/throw proves very useful in chaining N numbers of thenables.
#Bob-Fanger(accepted answer) addressed some part of this too.
Eg:
getData(id) {
return service.getData().then(dataList => {
const data = dataList.find(data => {
return data.id === id;
});
if (!data) {
// If I use Promise.reject here and use a reject handler in the parent then the parent might just be using the handler to route the error upwards in the chain
//If I use Promise.reject here and parent doesn't use reject handler then it goes to catch which can be just achieved using throw.
throw {
code: 404,
message: 'Data not present for this ID'
};
}
return configuration;
});
}
//somewhere up the chain
....getConfiguration()
.then(() => {
//successful promise execution
})
.catch(err => {
if (err.code) {
// checked exception
send(err);
} else {
//unchecked exception
send({
code: 500,
message: `Internal Server error: ${err}`
});
}
});
Using just these All I need to worry about is promise/then/catch along with resolve/return/throw anywhere in the chain.
The difference is that if an error occurs inside resolveHandler it won't be handled by the rejectHandler, that one only handles rejections in the original promise.
The rejectHandler is not used in combination with catch that much, because most of the time we only care about that something went wrong.
Creating only one errorhandler makes the code easier to reason about.
If a specific promise in the chain should handled differently that can be a reason to use a rejectHandler, but i'd probably write a catch().then().catch() in that case.
Neither is more useful than the other. Both the rejected handler and the catch callback are called when an error is thrown or a promise is rejected.
There is no "best practice" to use one over the other. You may see code use one or the other, but it's use will be based on what the code needs to achieve. The programmer may want to catch an error at different times in the chain and handle errors thrown at different times differently.
Hopefully the following will help explain what I mean:
somePromise
.then(
function() { /* code when somePromise has resolved */ },
function() {
/* code when somePromise has thrown or has been rejected.
An error thrown in the resolvedHandler
will NOT be handled by this callback */ }
);
somePromise
.then(
function() { /* code when somePromise has resolved */ }
)
.catch(
function() {
/* code when somePromise has thrown or has been rejected OR
when whatever has occurred in the .then
chained to somePromise has thrown or
the promise returned from it has been rejected */ }
);
Notice that in the first snippet, if the resolved handler throws then there is no rejected handler (or catch callback) that can catch the error. An error thrown in a resolved callback will not be caught by the rejectedHandler that is specified as the second argument to the .then
As stated in the post, provision of a resolve and reject handler in the same call to .then allows dealing with rejection of the previous promise separately from errors thrown within, or returning a rejected promise from, the success handler.
Because a rejection handler returning without throwing an error resumes the fufilled channel of a promise chain, a final catch handler will not be invoked if a previous rejection handler returns normally.
The question then devolves into use cases, cost of development and level of knowledge.
Use cases
In theory the two parameter form of then call could be used to retry an operation. But because hard coded promise chains are set up statically, retrying the operation is not simple. An easier way to retry might be to use an async function with try-catch statements surrounding await of a promise that may need to be retried as in this concept code:
async function() {
let retries = 3;
let failureErr = null;
while( retries--) {
try {
var result = await retryableOperationPromise()
return result;
}
catch( err) {
failureErr = err;
}
}
throw failureErr // no more retries
}
Other use cases may not be widespread.
Cost of development or commercial decisions.
If telling a user to retry later is acceptable it may be cheaper than doing anything about specific reasons for promise rejection. For example if I try to book a flight over midnight, when airlines put the prices up, I usually get told "an error occurred, try again later" because the price I was given at the start of booking will not be honored.
Knowledge (<opinion>)
I suspect that promise usage may often be based on example rather than in-depth knowledge of the subject. It is also possible program managers want to keep the code base as simple as possible for less experienced developers (probably a cost issue).
"Best practice" may not truly apply for making decisions on how to use promises if the usage is valid. Some developers and managers will avoid some forms of usage as a matter of principle, but not always based on technical merit.
I'm learning to convert my Node.js code style from callback to promise which seems to be the tendency and it has many advantages. To prevent the misunderstanding of the important points and benefits of the promise, I'm reading
document on MDN . I can understand Examples in this page, but I am not clear with the note that at the beginning of the document, it had mentioned :
Note: ... If the first argument is omitted or provided a non-function,
the new Promise that is created simply adopts the fulfillment state of
the Promise that then is called on (if it becomes fulfilled). If the
second argument is omitted or provided a non-function, the new Promise that
is created simply adopts the rejection state of the Promise that then is called
on (if it becomes rejected).
Sorry in advance if this is trivial.
Hope for the explanation with examples, thanks.
EDIT: Updated to better match the spec - see here and here.
The .then method calls one of two functions, depending on whether or not the Promise it's attached to has fulfilled or rejected. It then returns a new Promise based on the result of that call. This allows you to run different logic depending on whether or not a Promise was successful, and makes it possible to chain Promises together easily.
If you decide not to pass in one of those functions, however, it uses sensible defaults - which is what the note you posted is alluding to. It's probably a lot easier to demonstrate than to describe, though!
If you leave out the onRejected callback, like so:
myPromise.then(function (value) {
console.log("success!");
});
The result is the same as doing this:
myPromise.then(function (value) {
console.log("success!");
}, function (reason) {
throw reason;
});
If you leave out the onFulfilled callback, like so:
myPromise.then(null, function (reason) {
console.log("fail!");
});
The result is the same as:
myPromise.then(function (value) {
return value; // the same as returning Promise.resolve(value)
}, function (reason) {
console.log("fail!");
});
If you leave both out... it's basically pointless, but still:
myPromise.then();
This is effectively the same thing as:
myPromise.then(function (value) {
return value;
}, function (reason) {
throw reason;
});
Which is in turn, basically just:
myPromise
The other answers provide good explanations, but it might be easier to express this using the concept of skipping over.
If and when the promise fulfills, then the first argument to then is invoked (as long as it is a function); if and when the promise rejects, then the second argument to then is invoked (as long as it is there and is a function). In other cases, the .then is just skipped over.
Purists would object that it is incorrect to say the .then is "skipped over", and that what is really happening is that the .then creates a new promise which is equivalent to (or assumes the state of) the original promise. That's technically correct, but informally it's easier to talk and think about the .then getting "skipped".
Examples:
function log(v) { console.log("value", v); }
function err(e) { console.log("error", e); }
Promise.resolve(1).then(null, err).then(log);
^^^^^^^^^^^^^^^ "SKIPPED" (onFulfilled is null)
Promise.reject(1).then(log).catch(err);
^^^^^^^^^ "SKIPPED" (onRejected is not given)
For completeness, the corresponding behavior for catch is:
If and when the promise rejects, then the argument to catch is invoked (as long as it is a function). In other cases, the .catch is just skipped over.
Promise.resolve(1).catch(err).then(log);
^^^^^^^^^^ "SKIPPED" (promise did not reject)
If you think about it carefully, you will see that this all means that .then(null, handler) is exactly equivalent in every way to .catch(handler). So catch can be thought of as a kind of convenience routine.
But what's the point of allowing, but then ignoring, non-function handlers? Shouldn't they throw a TypeError or something instead? Actually, this is a "feature" which can be used as follows:
promise.then(isWednesday && wednesdayHandler)
If it's Wednesday, then this will evaluate to wednesdayHandler and we can do some special Wednesday processing. It it's not Wednesday, then this will evaluate to false, which is obviously not a function, so the whole then clause will be "skipped".
I don't have too much to add to this that the other answers don't already--just that I came to this question in the process of writing my own question about this, at which point SO miraculously suggested this one as a possible duplicate (when it did not come up in my previous search attempts).
Anyways the current documentation on MDN on the parameters to Promise.prototype.then have changed a bit since the OP and I think are still confusing, if not even moreso than before, so I thought I would add a follow-up answer concerning the current documentation which reads:
onFulfilled Optional
A Function called if the Promise is fulfilled. This function has one argument, the fulfillment value. If it is not a function, it is internally replaced with an "Identity" function (it returns the received argument).
What's confusing about this wording is it's not totally clear what is the antecedent of "received argument". Without already being familiar with the details of the Promises spec, one could read this as the "identity" function returning the argument received by the then() call. I.e. that something like this:
let promise = new Promise((resolve, reject) => resolve("value"));
let chained = promise.then("new value");
is equivalent to this:
let promise = new Promise((resolve, reject) => resolve("value"));
let chained = promise.then(() => "new_value");
so that the value resolved from chained is "new_value".
When in fact, "received value" refers to the resolved value of the original promise that .then() was chained from, i.e.:
let promise = new Promise((resolve, reject) => resolve("value"));
let chained = promise.then(() => "value");
So writing promise.then("not_a_callable") completely ignores "not a callable" and is resolved to the value that fulfilled the original promise, whatever it happens to have been.
Personally, I think this confusing behavior, but it is what it is.
I know how to create a promise in Kris Kowal's q with var defer = Q.defer();, calling defer.resolve(); and/or defer.reject() and return defer.promise. But reading the docs, it seem's there is an alternative way to create a promise...
From the docs:
Q.Promise(resolver)
Synchronously calls resolver(resolve, reject, notify) and
returns a promise whose state is controlled by the functions passed to
resolver. This is an alternative promise-creation API that has the
same power as the deferred concept, but without introducing another
conceptual entity.
If resolver throws an exception, the returned promise will be rejected
with that thrown exception as the rejection reason.
This is, what I've tried:
function () {
return Q.Promise(function (resolve, reject) {
(...do something...)
resolve(5); // or: reject(error);
});
}
But this doesn't work as expected!
Can someone give an example, how to use Q.Promise?
UPDATE:
Thanks for downvoting! I asked for an usage example, therefore a simple "you use it in a correct way" is more helpful! Btw: it fails silently and yes, I attached an error handler!
The reason, why the function is unnamed, is that I use it together with map and reduce to create a delayed chain of promises, but it seems, the resolver functions are never called... Therefore I asked for a (again) usage example...
Looking at your 2 examples, I'm guessing you are doing this:
var q = require('q');
Therefore Q.Promise won't work, but rather q.Promise will.
From what I have understood there are three ways of calling asynchronous code:
Events, e.g. request.on("event", callback);
Callbacks, e.g. fs.open(path, flags, mode, callback);
Promises
I found the node-promise library but I don’t get it.
Could someone explain what promises are all about and why I should use it?
Also, why was it removed from Node.js?
Since this question still has many views (like mine) I wanted to point out that:
node-promise looks rather dead to me (last commit was about 1 year ago) and contains nearly no tests.
The futures module looks very bloated to me and is badly documented (and I think that the naming conventions are just bad)
The best way to go seems to be the q framework, which is both active and well-documented.
Promises in node.js promised to do some work and then had separate callbacks that would be executed for success and failure as well as handling timeouts. Another way to think of promises in node.js was that they were emitters that could emit only two events: success and error.
The cool thing about promises is you can combine them into dependency chains (do Promise C only when Promise A and Promise B complete).
By removing them from the core node.js, it created possibility of building up modules with different implementations of promises that can sit on top of the core. Some of these are node-promise and futures.
A promise is a "thing" which represents the "eventual" results of an operation so to speak. The point to note here is that, it abstracts away the details of when something happens and allows you to focus on what should happen after that something happens. This will result in clean, maintainable code where instead of having a callback inside a callback inside a callback, your code will look somewhat like:
var request = new Promise(function(resolve, reject) {
//do an ajax call here. or a database request or whatever.
//depending on its results, either call resolve(value) or reject(error)
//where value is the thing which the operation's successful execution returns and
//error is the thing which the operation's failure returns.
});
request.then(function successHandler(result) {
//do something with the result
}, function failureHandler(error) {
//handle
});
The promises' spec states that a promise's
then
method should return a new promise that is fulfilled when the given successHandler or the failureHandler callback is finished. This means that you can chain together promises when you have a set of asynchronous tasks that need to be performed and be assured that the sequencing of operations is guaranteed just as if you had used callbacks. So instead of passing a callback inside a callback inside a callback, the code with chained promises looks like:
var doStuff = firstAsyncFunction(url) {
return new Promise(function(resolve, reject) {
$.ajax({
url: url,
success: function(data) {
resolve(data);
},
error: function(err) {
reject(err);
}
});
};
doStuff
.then(secondAsyncFunction) //returns a promise
.then(thirdAsyncFunction); //returns a promise
To know more about promises and why they are super cool, checkout Domenic's blog : http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/
This new tutorial on Promises from the author of PouchDB is probably the best I've seen anywhere. It wisely covers the classic rookie mistakes showing you correct usage patterns and even a few anti-patterns that are still commonly used - even in other tutorials!!
http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html
Enjoy!
PS I didn't answer some other parts of this question as they've been well covered by others.
Mike Taulty has a series of videos, each of them less than ten minutes long, describing how the WinJS Promise library works.
These videos are quite informative, and Mike manages to show the power of the Promise API with a few well-chosen code examples.
var twitterUrl = "http://search.twitter.com/search.json?q=windows";
var promise = WinJS.xhr({ url: twitterUrl });
promise = promise.then(
function (xhr) {
},
function (xhr) {
// handle error
});
The treatment of how exceptions are dealt with is particularly good.
In spite of the WinJs references, this is a general interest video series, because the Promise API is broadly similar across its many implementations.
RSVP is a lightweight Promise implementation that passes the Promise/A+ test suite. I quite like the API, because it is similar in style to the WinJS interface.
Update Apr-2014
Incidentally, the WinJS library is now open source.
Another advantage of promises is that error handling and exception throwing and catching is much better than trying to handle that with callbacks.
The bluebird library implements promises and gives you great long stack traces, is very fast, and warns about uncaught errors. It also is faster and uses less memory than the other promise libraries, according to http://bluebirdjs.com/docs/benchmarks.html
What exactly is a Promise ?
A promise is simply an object which represents the result of an async operation. A promise can be in any of the following 3 states :
pending :: This is the initial state, means the promise is neither fulfilled nor rejected.
fulfilled :: This means the promise has been fulfilled, means the value represented by promise is ready to be used.
rejected :: This means the operations failed and hence can't fulfill the promise.
Apart from the states, there are three important entities associated to promises which we really need to understand
executor function :: executor function defines the async operation which needs to be performed and whose result is represented by the promise. It starts execution as soon as the promise object is initialized.
resolve :: resolve is a parameters passed to the executor function , and in case the executor runs successfully then this resolve is called passing the result.
reject :: reject is another parameter passed to the executor function , and it is used when the executor function fails. The failure reason can be passed to the reject.
So whenever we create a promise object, we've to provide Executor, Resolve and Reject.
Reference :: Promises
I've been also looking into promises in node.js recently. To date the when.js seems to be the way to go due to its speed and resource use, but the documentation on q.js gave me a lot better understanding. So use when.js but the q.js docs to understand the subject.
From the q.js readme on github:
If a function cannot return a value or throw an exception without
blocking, it can return a promise instead. A promise is an object that
represents the return value or the thrown exception that the function
may eventually provide. A promise can also be used as a proxy for a
remote object to overcome latency.
Promise object represents the completion or failure of an asynchronous operation.
So in order to implement a promise, you need two parts:-
1.Creating Promise:
The promise constructor accepts a function called an executor that has
2 parameters resolve and reject.
function example(){
return new Promise (function(resolve , reject){ //return promise object
if(success){
resolve('success'); //onFullfiled
}else{
reject('error'); //onRejected
}
})
}
2.Handling Promise:
Promise object has 3 methods to handle promise objects:-
1.Promise.prototype.catch(onRejected)
2.Promise.prototype.then(onFullfiled)
3.Promise.prototype.finally(onFullfiled,onRejected)
example.then((data) =>{
//handles resolved data
console.log(data); //prints success
}).catch((err) => {
//handles rejected error
console.log(err); //prints error
})