How does a thenable object get rejected in JavaScript? - javascript

I know that a thenable has the then method, but how does Promise know the state of the thenable objected has moved to rejected?
Example:
Here, $.ajax is a thenable and can be ducktyped as a Promise if you do this:
Promise.resolve($.ajax({ url: '/test' }))
But how does the promise that this expression returns handle the catch case?

A Promises/A+ then method does take two callbacks - one for the fulfilment and one for the rejection case. You would not use the .then(…).catch(…) pattern but .then(…, …) - the second callback is the "catch case" (notice that .catch(…) is nothing but .then(null, …)).
This is how thenables are assimilated - when the second callback gets called, they reject the promise with the error. Example:
var rejectingPromise = Promise.resolve({
then: function(onSuccess, onError) {
onError(new Error);
}
});

Related

I'm trying to go step-by-step to see how Promise.prototype.catch receives a Promise. Is my understanding right?

function fetchDog(){
fetch("https://dog.ceo/api/breeds/image/fail")
.then(response => response.json())
.then(data => console.log(data))
.catch(function(err) {
console.log('Fetch problem');
});
};
fetchDog();
Using the above example I would like to clarify how .catch here receives the rejected Promise. It's also a good exercise in reading MDN for me.
1 .
Looking at this statement from MDN:
If the Promise that then is called on adopts a state (fulfillment or
rejection) for which then has no handler, a new Promise is created
with no additional handlers, simply adopting the final state of the
original Promise on which then was called.
I translate that to mean, in my example, the .thens return a new promise that is a copy of the promise that .then was called on.
2 .
The Promise.prototype.catch spec also says it behaves the same as calling Promise.prototype.then(undefined, onRejected).
I interpret this to mean, in my example, that the first callback in catch is the onRejected parameter. Therefore, when catch receives a rejected promise, it executes console.log('Fetch problem');.
I also interpret this to mean that when catch invariably receives a fulfilled promise, it returns undefined? (I haven't thought of a way to test this in the console).
3 .
I also read in the .then spec:
If a handler function: doesn't return anything, the promise returned
by then gets resolved with an undefined value.
Therefore, in my code snippet, I interpret this to mean catch returns a promise whose value is undefined.
Based on this understanding, so long as the fetch line returned a fulfilled promise, this fulfilled promise would find its way to catch and catch's callback wouldn't execute. catch would return undefined. (I can't think of a way to test this). I suspect my understanding is wrong.
When catch invariably receives a fulfilled promise, it returns undefined?
No. Calling .catch() will always return a promise. It does that before even knowing whether the promise that it was called on is fulfilled, rejected or still pending.
I interpret this to mean catch returns a promise whose value is undefined.
Yes. You can test this easily with
function handleError(p1) {
const p2 = p1.catch(err => {
console.log('handling problem', err);
});
p2.then(res => {
console.log('final promise fulfilled with', res);
});
}
// handleError(Promise.resolve('success'));
handleError(Promise.reject('error'));

Understanding the .catch method in promises

I'm wanting to clarify how a promise is passed to .catch and what .catch does with it.
Using this as an example:
function fetchDog(){
fetch("https://dog.ceo/api/breeds/image/fail")
.then(response => response.json())
.then(data => console.log(data))
.catch(function(err) {
console.log('Fetch problem');
});
};
fetchDog();
Looking at this statement from MDN:
If the Promise that then is called on adopts a state (fulfillment or
rejection) for which then has no handler, a new Promise is created
with no additional handlers, simply adopting the final state of the
original Promise on which then was called.
I translate that to mean, in my example, the .thens return a new promise that is a copy of the promise that .then was called on.
By the time it reaches .catch, I know that .catch prints something to the console. The spec also says it behaves the same as calling Promise.prototype.then(undefined, onRejected).
Therefore, based on this excerpt from the .then spec:
If a handler function: doesn't return anything, the promise returned
by then gets resolved with an undefined value.
I expect .catch to return a new promise that 'gets resolved with' an undefined value. (What exactly does that mean, for a promise object to get 'resolved with' an undefined value)?
Is this true?
.then() calls its callback when the promise is resolved. .catch() only calls its callback when the promise is rejected.
If fetch() is successful, it resolves its promise, so only the .then() callbacks are called.
If fetch() gets an error, it rejects its promise, and the .catch() callbacks will be called. Also, if response.json() gets an error (e.g. the response was not valid JSON), it will reject the promise, and .catch() will call its callback.

Javascript: when new a Promise instance, where are the parameters(resolve,reject) from [duplicate]

I have begun learning javascript promises. But I just can't understand the concept of promises.
The thing that bothers me most is who is passing the Resolver and Reject function to a promise constructor ?
See this example of Promise:
function getImage(url){
return new Promise(function(resolve, reject){
var img = new Image()
img.onload = function(){
resolve(url)
}
img.onerror = function(){
reject(url)
}
img.src = url
})
}
Now who does pass resolve and reject methods, as my understanding of javascript says to me that this script will throw unknown variable errors as resolve and rejects are not defined?
getImage('doggy.jpg').then(function(successurl){
document.getElementById('doggyplayground').innerHTML = '<img src="' + successurl + '" />'
}).catch(function(errorurl){
console.log('Error loading ' + errorurl)
})
Now you see a method like the above, the only way these methods(resolve and reject) are passed are via then and catch as used in above method call to getImage.
The thing that bothers me most is who is passing the Resolver and Reject function to a promise constructor ?
Nobody.
The functions are passed by the promise constructor.
They are passed to the function which you pass as the first argument to the promise constructor.
The Promise constructor is initialized with a callback, and the constructor passes reject and resolve as parameters when the callback is called.
Here is a simple demo:
class PromiseDemo {
constructor(cb) {
cb(this.resolve.bind(this), this.reject.bind(this));
}
resolve(d) {
console.log('resolve', d);
}
reject(d) {
console.log('reject', d);
}
}
new PromiseDemo((resolve, reject) => {
Math.random() > 0.5 ? resolve('1') : reject('1');
});
I had the same problem in understanding Promises.You need to look at the process of promise creation carefully.
when you write
var promise= new Promise(function(resolve,reject){...})
you are actually invoking constructor of Promise class or creating an object of Promise class. Now Promise constructor requires a function callback.
Now resolve and reject are just function arguments and not any other values.
You can write anything in place of resolve or reject like resolveHandler or rejectHandler.
These resolve or reject are nothing but the function callback that Promise calls when Promise is executed.
Now resolve is called when Promise is executed successfully and reject is called when promise is executed with some error or unsuccessfully .
The argument with which resolve is called can be accessed inside then like this
getImage().then(function(valueSentInResolve){ console.log('')})
The argument with which reject is called can be accessed inside catch like this
getImage().then(function(valueSentInResolve)
{//..do something}
).catch(function(errorSentInReject){
console.log('error',errorSentInReject )
})
I hope that helps.Let me know if I said anything wrong.
I have been studying Promises all day, and had the same question. I finally figured it out.
When you make a Promise object, you give the Promise Constructor an executor, which can be any function, as long as it has this signature.
anyFunction(resolutionFunction, rejectionFunction){
// typically, some asynchronous operation.
}
So any function with 2 functions as the arguments can be used. The first function is what you call when it works, the second is what you call when it breaks. You can name those functions whatever you want as well.
The Promise Constructor takes the function you pass in and does a few things with it.
It takes those 2 function arguments and generates a corresponding pair of functions that are "connected" to the Promise object.
It runs the executor
It ignores any return value from your executor
Now in your executor function when the promise resolves you call the positionally first function and pass it one value. It will look something like:
resolutionFunction(value)
You may be wondering, where is resolutionFunction defined? Remember the Promise Constructor defined that function for us. So we can call resolutionFunction without having to define it ourselves. Behind the scenes, when we call that resolutionFunction generated by the Promise Constructor, it sets the state of the promise to fulfilled, calls the function inside the promiseObject.then function, and passes the value into the .then function so you can use it.
You would call the 2nd positional function if the promise failed and the same things would happen and you could deal with the failure.
This Mozilla Doc on the Promise Constructor was very helpful.
Here is a short examples that shows what I explained above.
function anyFunction(callThisFunctionWhenItWorks, callThisFunctionWhenItBreaks) {
let importantNumber = 10; //change to 11 if you want the promise to reject
if (importantNumber == 10) {
callThisFunctionWhenItWorks('Hooray, success, so we call resolved for the promise.');
} else {
callThisFunctionWhenItBreaks('Boo, rejected because important number is not equal to 10');
}
}
//make a new promise
const examplePromise = new Promise(anyFunction);
//use the promise
examplePromise.then(function(result) {
console.log(result);
}).catch(function (error) {
console.log(error);
})
The promise library creates and passes those functions, along with all the other metadata needed to track the promise and record completion, store state and progress, cancel it, etc.
The folks behind Bluebird have published some info on how the library works internally, and you can see more in the Bluebird source.
does this make sense? This explanation could be completely incorrect!!
We provide the logic which should run asynchronously. The logic should accept 2 functions, resolve and reject. The reference of these functions is provided by Promise. These functions should be called by our logic when we have the final value or error. The Promise created initially is in Pending state. Calling resolve and reject changes the state to Fulfilled or Rejected respectively.
executeFunction(res,rej) = {
do some op, say DB query.
if (success) res(value) //executeFunction uses the resolving functions to change state of the Promise. Calling res fulfills the promise with value
if (fail) rej(reason)//executeFunction uses the resolving functions to change state of the Promise. Calling rej rejects the promise with reason
}
Rather than calling executeFunction directly (which would make the call synchronous), we create a Promise will will run the executeFunction code in a separate thread (asynchronously) let p = Promise(executeFunction(res,rej));. We get back a reference of the Promise.
My guess is that internally in the Promise, the following happens
Promise(e(res,rej)) = {
// the Promise's constructor creates a new promise, initially in the pending state. It calls `e` (the executeFunction function) and provides references to the resolving functions to it that can be used to change its state.
state = pending;
e(_res,_rej); //starts my op. asynchronously (a new thread). Reference to resolving functions, _res, _rej is provided. _res and _rej are Promise's internal functions (see below)
//constructor doesn't return till the async thread finishes
}
_res (value){ //Promise's internal method
//probably sets the state of promise to Fulfilled and store the result of the Promise
state = fulfilled
resolvedValue = value;
}
_rej {//Promise's internal method
probably sets the state of promise to Rejected and store the result of the Promise
state = rejected
resolvedValue = error;
}
Creating the Promise starts the execution of the code asynchronously. Now we are interested in knowing what is the result of executeFunction (we don't care when executeFunction finishes). To do this, we call then of the Promise p. then takes two optional arguments and registers them as callbacks. I am not sure when and who calls these callbacks. I know that then returns another Promise but I am not able to understand how that works
then(executeFnIfPromiseResolved, executeFnIfPromiseRejected):Promise {
register executeFnIfPromiseResolved as callback
register executeFnIfPromiseRejected as callback
//NOT SURE WHO AND WHEN THE CALLBACKS ARE CALLED
//then needs to return Promise. What would be the executor function of that Promise?
}

When or who does pass resolve and reject functions to JS promises?

I have begun learning javascript promises. But I just can't understand the concept of promises.
The thing that bothers me most is who is passing the Resolver and Reject function to a promise constructor ?
See this example of Promise:
function getImage(url){
return new Promise(function(resolve, reject){
var img = new Image()
img.onload = function(){
resolve(url)
}
img.onerror = function(){
reject(url)
}
img.src = url
})
}
Now who does pass resolve and reject methods, as my understanding of javascript says to me that this script will throw unknown variable errors as resolve and rejects are not defined?
getImage('doggy.jpg').then(function(successurl){
document.getElementById('doggyplayground').innerHTML = '<img src="' + successurl + '" />'
}).catch(function(errorurl){
console.log('Error loading ' + errorurl)
})
Now you see a method like the above, the only way these methods(resolve and reject) are passed are via then and catch as used in above method call to getImage.
The thing that bothers me most is who is passing the Resolver and Reject function to a promise constructor ?
Nobody.
The functions are passed by the promise constructor.
They are passed to the function which you pass as the first argument to the promise constructor.
The Promise constructor is initialized with a callback, and the constructor passes reject and resolve as parameters when the callback is called.
Here is a simple demo:
class PromiseDemo {
constructor(cb) {
cb(this.resolve.bind(this), this.reject.bind(this));
}
resolve(d) {
console.log('resolve', d);
}
reject(d) {
console.log('reject', d);
}
}
new PromiseDemo((resolve, reject) => {
Math.random() > 0.5 ? resolve('1') : reject('1');
});
I had the same problem in understanding Promises.You need to look at the process of promise creation carefully.
when you write
var promise= new Promise(function(resolve,reject){...})
you are actually invoking constructor of Promise class or creating an object of Promise class. Now Promise constructor requires a function callback.
Now resolve and reject are just function arguments and not any other values.
You can write anything in place of resolve or reject like resolveHandler or rejectHandler.
These resolve or reject are nothing but the function callback that Promise calls when Promise is executed.
Now resolve is called when Promise is executed successfully and reject is called when promise is executed with some error or unsuccessfully .
The argument with which resolve is called can be accessed inside then like this
getImage().then(function(valueSentInResolve){ console.log('')})
The argument with which reject is called can be accessed inside catch like this
getImage().then(function(valueSentInResolve)
{//..do something}
).catch(function(errorSentInReject){
console.log('error',errorSentInReject )
})
I hope that helps.Let me know if I said anything wrong.
I have been studying Promises all day, and had the same question. I finally figured it out.
When you make a Promise object, you give the Promise Constructor an executor, which can be any function, as long as it has this signature.
anyFunction(resolutionFunction, rejectionFunction){
// typically, some asynchronous operation.
}
So any function with 2 functions as the arguments can be used. The first function is what you call when it works, the second is what you call when it breaks. You can name those functions whatever you want as well.
The Promise Constructor takes the function you pass in and does a few things with it.
It takes those 2 function arguments and generates a corresponding pair of functions that are "connected" to the Promise object.
It runs the executor
It ignores any return value from your executor
Now in your executor function when the promise resolves you call the positionally first function and pass it one value. It will look something like:
resolutionFunction(value)
You may be wondering, where is resolutionFunction defined? Remember the Promise Constructor defined that function for us. So we can call resolutionFunction without having to define it ourselves. Behind the scenes, when we call that resolutionFunction generated by the Promise Constructor, it sets the state of the promise to fulfilled, calls the function inside the promiseObject.then function, and passes the value into the .then function so you can use it.
You would call the 2nd positional function if the promise failed and the same things would happen and you could deal with the failure.
This Mozilla Doc on the Promise Constructor was very helpful.
Here is a short examples that shows what I explained above.
function anyFunction(callThisFunctionWhenItWorks, callThisFunctionWhenItBreaks) {
let importantNumber = 10; //change to 11 if you want the promise to reject
if (importantNumber == 10) {
callThisFunctionWhenItWorks('Hooray, success, so we call resolved for the promise.');
} else {
callThisFunctionWhenItBreaks('Boo, rejected because important number is not equal to 10');
}
}
//make a new promise
const examplePromise = new Promise(anyFunction);
//use the promise
examplePromise.then(function(result) {
console.log(result);
}).catch(function (error) {
console.log(error);
})
The promise library creates and passes those functions, along with all the other metadata needed to track the promise and record completion, store state and progress, cancel it, etc.
The folks behind Bluebird have published some info on how the library works internally, and you can see more in the Bluebird source.
does this make sense? This explanation could be completely incorrect!!
We provide the logic which should run asynchronously. The logic should accept 2 functions, resolve and reject. The reference of these functions is provided by Promise. These functions should be called by our logic when we have the final value or error. The Promise created initially is in Pending state. Calling resolve and reject changes the state to Fulfilled or Rejected respectively.
executeFunction(res,rej) = {
do some op, say DB query.
if (success) res(value) //executeFunction uses the resolving functions to change state of the Promise. Calling res fulfills the promise with value
if (fail) rej(reason)//executeFunction uses the resolving functions to change state of the Promise. Calling rej rejects the promise with reason
}
Rather than calling executeFunction directly (which would make the call synchronous), we create a Promise will will run the executeFunction code in a separate thread (asynchronously) let p = Promise(executeFunction(res,rej));. We get back a reference of the Promise.
My guess is that internally in the Promise, the following happens
Promise(e(res,rej)) = {
// the Promise's constructor creates a new promise, initially in the pending state. It calls `e` (the executeFunction function) and provides references to the resolving functions to it that can be used to change its state.
state = pending;
e(_res,_rej); //starts my op. asynchronously (a new thread). Reference to resolving functions, _res, _rej is provided. _res and _rej are Promise's internal functions (see below)
//constructor doesn't return till the async thread finishes
}
_res (value){ //Promise's internal method
//probably sets the state of promise to Fulfilled and store the result of the Promise
state = fulfilled
resolvedValue = value;
}
_rej {//Promise's internal method
probably sets the state of promise to Rejected and store the result of the Promise
state = rejected
resolvedValue = error;
}
Creating the Promise starts the execution of the code asynchronously. Now we are interested in knowing what is the result of executeFunction (we don't care when executeFunction finishes). To do this, we call then of the Promise p. then takes two optional arguments and registers them as callbacks. I am not sure when and who calls these callbacks. I know that then returns another Promise but I am not able to understand how that works
then(executeFnIfPromiseResolved, executeFnIfPromiseRejected):Promise {
register executeFnIfPromiseResolved as callback
register executeFnIfPromiseRejected as callback
//NOT SURE WHO AND WHEN THE CALLBACKS ARE CALLED
//then needs to return Promise. What would be the executor function of that Promise?
}

difference between resolve and onFulfilled

What is the difference between
resolve and onFulfilled in javascript promises ?
Similarly, what is the difference between
reject and onRejected ?
In simple words, I would just ask how does onsuccess callback of Promise.then(onsuccess, onreject) differs from Promise.resolve ()?
I am reading Javascript with Promises by Daniel Parker.
The book has mentioned both of them but I have not realized the difference between two yet.
While describing then in promises:
promise.then
promise.then([onFulfilled], [onRejected]) returns promise
The promise.then() method accepts an onFulfilled callback and an
onRejected
callback. People generally register onRejected callbacks using promise.catch()
instead of passing a second argument to then . The function then returns a promise that is resolved by the return value of the
onFulfilled or onRejected callback. Any error thrown inside the callback rejects the new promise with that error.
Also,
Promise.resolve
Promise.resolve([value|promise]) returns promise The Promise.resolve()
function is a convenience function for creating a promise that is
already resolved with a given value. If you pass a promise as the
argument to Promise.resolve(), the new promise is bound to the promise
you provided and it will be fulfilled or rejected accordingly.
Code:
function settled(promises) {
var alwaysFulfilled = promises.map(function (p) {
return p.then(
function onFulfilled(value) {
return { state: 'fulfilled', value: value };
},
function onRejected(reason) {
return { state: 'rejected', reason: reason };
}
);
});
return Promise.all(alwaysFulfilled);
}
};
simply put
when a promise is resolved any current or future onFullfilled functions will be called with the parameter to that function being the value of the resolve function
similarly with reject/onRejected

Categories

Resources