I am sure that all the codes below, except resolve(Promise.resolve(p2)), are synchronous.
So I expect the result is p2 first since the p2.then run first. However p1 comes out first in console.
MDN has nothing related to the question.
Does the spec has some details? Can someone make it clear step by step what happens in resolving a promise?
Chrome v60.0.3112.113
My code is:
var p1 = new Promise(function(resolve, reject){
resolve("p1");
});
var p2 = new Promise(function(resolve, reject){
//resolve("p2");
var tempP = Promise.resolve("p2"); // for better description in discussion
resolve(tempP);
});
p2.then(function(value){
console.log(value)
})
p1.then(function(value){
console.log(value);
});
I am sure that all the codes below, except resolve(Promise.resolve(p2)), are synchronous.
No. then callbacks are never called synchronously, they're always asynchronous (and that's good). That means their relative order is indeterminate, and depends on when the respective promise was fulfilled. If you ever care about the order of callbacks, make it explicit by chaining the promises onto each other.
The order of fulfillment in your example depends on the value that you resolved the promises with. Notice that the new Promise callback and therefore your resolve are synchronous, in both p1 and p2. Every resolution is put into a queue - at least with native ES6 promises that you appear to be using. The difference is that your p2 is resolved with Promise.resolve("p2"), which will resolve p2 with the result of that other promise - which is put back onto the queue again. Therefore the fulfillment of p1 happens first, and the callback is called before the fulfillment callback of p2.
So what happens step-by-step is
The new Promise calls the constructor callback, which in turn
resolves the new promise with the value "p1" - fulfilling it
The new Promise returns and the value is assigned to p1.
The new Promise calls the constructor callback, which in turn
constructs another promise fulfilled with the value "p2"
and resolves the new promise with it - which adds another resolve as a callback for when that promise completes
The inner promise schedules that callback as it is already is fulfilled
The new Promise returns and the value is assigned to p2.
The p2.then is called and registers the fulfillment callback
The p1.then is called and schedules the fulfillment callback, as p1 is already fulfilled
After that, asynchronously:
the inner promise's callback is called and resolves p2 with the value "p2 - fulfilling it and scheduling its registered callbacks
the p1 callback is called and logs "p1"
the p2 callback is called and logs "p2"
This is the expected behavior.
Promise.resolve() returns a promise which is guaranteed to be asynchronous. So the value it returns will always resolve at the earliest on the next event loop after it is called. So in this case what happens is:
P2 returns a promise
P1 returns a promise
Next loop
P2 calls then() which resolves to a new promise that's scheduled for the next loop
P1 calls then() callback which resolves to a value which is printed
Next loop
P2's returned promise resolves and is printed
Both p1 and p2 are async, as you are creating a Promise.
New Promise() creates a new promise, and once it is created the following code is executed, but execution inside the Promise is done later (or at the same time; async).
p2.then is not executed before p1.then. The .then function is executed, once the promise resolves, and p1 resolves before p2
You code above :
var p2 = new Promise(function(resolve, reject){
resolve(Promise.resolve("p2"));
});
Is equivalent to doing :
var p2 = new Promise(function(resolve, reject) {
resolve(new Promise(function(resolve1, reject1) {
resolve1("p2");
}));
});
Which creates a new promise that is although immediately resolved, will be executed at the end of the call queue.
Related
I am new to promises and have studied it. So my code and my understanding:
sql.connect(config).then(function(connection) {
return connection.request().query('select * from Users')
}).then(function(result) {
console.dir(result);
res.send(result);
}).catch((err) => {
console.log(err);
res.send(err)
});
}) // extra?
In the first line, the connect method returns a promise so on that, when I call a function then (if connect had success). The then takes callbacks i.e. "successCB", "failureCB" as arguments which actually represent the result or error returned by the connect promise. Correct?
Also, the "successCB" is returning the promise (from .query).
then is again called on the previous promise returned by then.
In case of then used on connect() why is the then taking a callback and how does it know of connect's success since connect has already returned the result i.e. "successCB"?
I'm not 100% certain if you are correct, but this is how I would explain it. Lets say we have a promise A.
Calling then() always returns a new promise (Lets call it B)
If the callback returns a promise C, then promise B will resolve or fail with the result of promise C.
If any of the callbacks returns a non-promise value X, then promise B will resolve with value X
If an exception was thrown in the callback, then promise B will fail with the exception.
If the main promise A failed, and no failure callback was given, then promise B will also fail with the same error.
Personally I found learning this very confusing, because it requires quite a complex mental model to fully grasp this. The day I fully understood this is the day that I wrote my own Promise class. I would recommend anyone who fully wants to grasp promises in every detail to take the time to do this.
In the first line, the connect method returns a promise so on that, I call a function then (if connect had success).
Almost: the then method is called irrespective of the connect promise's result. Note that the promise is most likely still pending when the then method is called. It is called (obviously) synchronously.
The then takes callbacks i.e. successCB, failureCB as an args which actually represents the result or error returned by the connect promise. Correct?
Those callbacks are registered by the promise object, and one of them will be called later when the promise resolves: it can either fulfil or reject. If the promise never resolves, neither will be called. In your case, you provided just one function, the one that will be called when the promise fulfils.
Also, the successCB is returning the promise (from .query).
True. The promise that was created when the outer then was executed will take over the status/value of the promise that was returned here.
then is again called on the previous promise returned by then.
Yes, but again, it is called immediately. All chained then/catch methods are called synchronously and their job is to register the callbacks and to return a promise.
The asynchronous part is when the respective callbacks are called. This is when the cascading effect takes place. Once the first promise (query()) in the chain resolves, the respective callback is called and that call resolves (fulfils or rejects) the promise that was already returned by then, which triggers a next callback... etc
Order of execution
Part A
sql.connect(config)
calls connect and returns a promise
.then(......)
calls then on the promise of A.1, registers the callback and returns a promise
.catch(.....)
calls catch on the promise of A.2, registers the callback and returns a promise.
This happens to be the last one in the chain, so this promise is the value of the whole expression.
At this point the synchronous part ends. If there is other calling code on the callstack, it gets executed, but eventually the call stack will be empty.
Part B
Then, some time later, there is an event indicating that the promise of A.1 is resolved, let's assume it fulfils (i.e. success). Then the first callback is executed:
connection.request() is executed
it calls request which returns an object with the query method (among others)
.query('select * from Users') is executed
it calls query with the SQL and returns a promise
return is executed
the callback returns the promise of B.2, which becomes linked with the promise that was created in step A.1.
At this point the promise of step A.1, is still pending. Its destiny is tied up now with the promise that was returned by query, B.2. It that one resolves, A.1 will also resolve (with the same state & value/error).
Part C
Then, some time later, there is an event indicating that the promise of step A.1 is resolved, let's assume it fulfils. Then the second callback is executed:
console.dir(result) is executed
res.send(result) is executed
Nothing is returned, so the promise of 1.B fulfils with value undefined
This fulfilment creates a next asynchronous job to execute (part D)
Part D
The promise returned by catch (A.3) resolves with the value with which C.3 resolved, i.e. it fulfils with value undefined. The callback it had registered is not executed, as it is not relevant for this scenario.
Thanks for replies and I have already selected the answer. Based on the input given by you people this is what I have understood further.
sql.connect(config).then(function(connection) {
return connection.request().query('select * from Users')
})
In the code given above, sql.connect part is using an SQL module to call a connect() method which is supposed to return a promise (in case of failure returns an error else a connection object). On connect() we call a then() method which takes a callback function function(connection) to get registered so that can be called later at the point where connect returns a promise (in case of success i.e. connection object) and later
.then(function(result) {
console.dir(result);
res.send(result);
}).
is called on the promise returned by .query('select * from Users') part of the previous .then() method's callback function and so on.
I want to fulfill a promise with some other promise. The point is that I really want to get access to the (still pending) second promise as soon as the first promise is fulfilled. Unfortunately, I only seem to be able to get the second promise's resolution value once both both promises are fulfilled.
Here's the use case that I have in mind:
var picker = pickFile();
picker.then( // Wait for the user to pick a file.
function(downloadProgress) {
// The user picked a file. The file may not be available just yet (e.g.,
// if it has to be downloaded over the network) but we can already ask
// the user some more questions while the file is being obtained in the
// background.
...do some more user interaction...
return downloadProgress;
}
).then( // Wait for the download (if any) to complete.
function(file) {
// Do something with the file.
}
)
The function pickFile displays a file picker where the user may pick a file either from their own hard drive or from a URL. It returns a promise picker that is fulfilled as soon as the user has picked a file. At this point, we may still have to download the selected file over the network. Therefore, I cannot fulfill picker with the selected file as resolution value. Instead, picker should be fulfilled with another promise, downloadProgress, which in turn will eventually be fulfilled with the selected file.
For completenes, here's a mock implementation of the pickFile function:
function pickFile() {
...display the file picker...
var resolveP1 = null;
var p1 = new Promise(
function(resolve, reject) {
resolveP1 = resolve;
}
);
// Mock code to pretend the user picked a file
window.setTimeout(function() {
var p2 = Promise.resolve('thefile');
resolveP1(p2); // <--- PROBLEM: I actually want to *fulfill* p1 with p2
}, 3000);
return p1;
}
The problem in the marked line is that I would like to fulfill the promise p1 with the new promise p2, but I only know how to resolve it. The difference between fulfilling and resolving is that resolving first checks if the supplied value p2 is again a promise. If it is, then fulfillment of p1 will be deferred until p2 is fulfilld, and then p1 will be fulfilled with p2's resolution value instead of p2 itself.
I could work around this issue by building a wrapper around p2, i.e. by replacing the line
resolveP1(p2); // <--- PROBLEM: I actually want to *fulfill* p1 with p2
from the second code example by
resolveP1({promise: p2});
Then, in the first code example, I'd have to replace the line
return downloadProgress;
by
return downloadProgress.promise;
But this seems like a bit of a hack when all I really want to do is just fulfill (instead of resolve) a promise.
I'd appreciate any suggestions.
There doesn't seem to be a solution apart from the workaround I already described in the question. For future reference, if you want to fulfill (rather than resolve) a promise p with a value val, where val is another promise, then just calling the promise resolution function for p with argument val won't work as expected. It would cause p to be "locked in" on the state of val, such that p will be fulfilled with val's resolution value once val is fulfilled (see spec).
Instead, wrap val in another object and resolve p with that object:
var resolveP; // Promise resolution function for p
var p = new Promise(
function(resolve, reject) {
resolveP = resolve;
}
);
function fulfillPwithPromise(val) { // Fulfills p with a promise val
resolveP({promise: val});
}
p.then(function(res) {
// Do something as soon as p is fulfilled...
return res.promise;
}).then(function(res) {
// Do something as soon as the second promise is fulfilled...
});
This solution works if you already know that val is a promise. If you cannot make any assumptions about val's type, then you seem to be out of luck. Either you have to always wrap promise resolution values in another object, or you can try to detect whether val has a field then of type "function" and wrap it conditionally.
That said, in some cases the default behavior of promise resolution may actually have the desired effect. So only use the workaround described above if you are sure that you want to fulfill instead of resolve the first promise with the second one.
Although different people use different terms, in common terminology, "fulfill" means to put a promise in the "success" state (as opposed to "reject")--the state that will trigger then then handlers hanging off it.
In other words, you cannot "fulfill" a promise with a promise. You can fulfill it with a value. (By the way, the term "resolve" is usually meant as either of fulfilling or rejecting.)
What you can do is return a promise from a .then handler and that will have the effect of essentially replacing the original promise with the returned promise.
Here is a simple example of doing that:
asyncTask1 . then(asyncTask2) . then(processData)
where asyncTask1 is a promise, and asyncTask2 is a function which returns a promise. So when asyncTask1 is fulfilled (done successfully), then asyncTask2 runs, and the promise returned by the .then is "taken over" by the promise asyncTask2 returns, so that when it finishes, the data can be processed.
I can do something similar by calling Promise.resolve with a promise as parameter. It's a bit of a misnomer, because I'm not resolving the promise in the technical sense. Instead, the new promise created is "inhabited" by the promise I passed in. It's also useless, because using the result is exactly the same as using the promise I passed in:
Promise.resolve(asyncTask2)
behaves exactly the same as
asyncTask2
(assuming asyncTask2 is already a promise; otherwise Promise.resolve has the effect of creating a promise which is immediately fulfilled with the passed in value.)
Just as you can pass a promise to Promise.resolve, you can pass a promise to the resolve function provided to you as a parameter of the promise constructor callback. If the parameter you pass to resolve is a non-promise, the promise immediately fulfills with that value. However, if the parameter you pass to resolve is another promise, that promise "takes over the body" of the promise you are constructing. To put it another way, the promise you are constructing starts to behave exactly as the the promise passed to resolve.
By "behave exactly" I mean, if the promise you pass in to resolve is already fulfilled, the promise you are constructing is instantly fulfilled with the same value. If the promise you pass in to resolve is already rejected, the promise you are constructing is instantly rejected with the same reason. If the promise you pass in to resolve is not resolved yet, then any then handlers you hang off the promise you are constructing will be invoked if and when the promise you pass to resolve is resolved.
Just as it is confusing that Promise.resolve may result in a promise which is not actually resolved, it is similarly confusing that calling the resolve function handed to you as a parameter to the promise constructor may not actually resolve the promise being constructed if you call it with an unresolved promise. Instead, as I've said a couple of times now, it has the effect of putting the promise being constructed in a state of total congruence with the promise passed to resolve.
Therefore, unless I am missing the point of your question, pickfile could be written as
function pickFile() {
return new Promise(function(resolve, reject) {
...display the file picker...
// Mock code to pretend the user picked a file
window.setTimeout(function() {
resolve('thefile');
});
}
I didn't really understand your question clearly, so this might not be what you want. Please clarify if you care to.
Found a similar solution in the process of moving away from Angular's $q to the native Promise feature. Promise.all could be an option (in cases of independent parallel async tasks) by passing around an appropriate object, or something decorated with the state, passing it off to whatever is ready when appropriate. In the Promise.all sample below note how it recovers in one of the promises--took me awhile to realize how to redirect the result of a chain. The result of the all is just the last promise's return. While this doesn't answer the question's title, using return Promise.reject(<an-object-including-a-promise>) (or resolve) gives a series and/or group of async tasks shared access and control along the way. In the case of picking, downloading then working with a file I'd take out the progress-event handling then do: pickFile.then(download,orFailGracefully) with downloadProgress handled within the download onResolve handler (download-progress doesn't appear to be an async task). Below are related experiments in the console.
var q = {
defer: function _defer(){
var deferred = { };
deferred.promise = new Promise(function(resolve, reject){
deferred.resolve = resolve;
deferred.reject = reject;
});
return deferred;
}
};
var communityThatCares = q.defer();
communityThatCares.promise.then(function(someGood){
console.log('someGood', someGood);
return someGood;
}, function(someBad){
console.warn('someBad', someBad);
return someBad;
});
(new Promise(function(resolve, reject){ communityThatCares.about = 'communityThatCares'; setTimeout(resolve,1000, communityThatCares); }))
.then(
function(e){
console.log(3,e); return e.resolve(e);
}, function(e){
console.warn(3, e); return e.reject(e);
});
var todo = {
find:'swan'
};
var greaterGood = [(
(new Promise(function(res,rej){ res(todo); })).then(function(e){ e.stuff = 'things'; return e; }),
(new Promise(function(res,reject){
reject(todo);
})).then(function(e){ return e; }
,function(e){
console.warn(1,e);
e.recover = 'uh oh';
return Promise.resolve(e);
}).then(function(e){ console.log(2,e); return e; }),
(new Promise(function(res,rej){ res(todo); })).then(function(e){ console.log(1,e); e.schedule = 'today'; return e; },function(e){ console.warn(1,e); return e; }).then(function(e){ console.log(2,e); return e; }))
];
var nkay = Promise.all( greaterGood )
.then(function(todo){
console.log('all',todo[0]); return todo;
}, function(todo){
console.warn('all',todo[0]); return todo;
});
If I was to have an active promise and I wanted to start a new promise but wait until that one was fulfilled would
var newPromise = Promise.resolve(stillActivePromise);
mean any chains on newPromise onwards would wait until stillActivePromise had fulfilled?
(lets pretend someActivePromise has a setTimeout(..., 10000); or something so you may want to start chaining new stuff but waiting for existing stuff to fully fullfil, be it a rejection or a resolution)
if Promise.resolve is given a "pending" promise as it's argument, it will "wait" for that promise to resolve (fulfill or reject) and will take on the state and value of the passed in promise
Let's say I have a Promise like this:
var promise = new Promise(function(resolve, reject) {
// Do some async thing
});
promise.then(function(response) {
// Then do some other stuff
});
What happens if the async Promise completes before I call .then()? Normally, I'd only have long running tasks in the Promise function, but what if it completes really quickly one time?
As expected: then callback will get called immediately in this case if then was called after promise has already resolved.
It's easy to test:
var promise = new Promise(function(resolve, reject) {
resolve(123);
});
setTimeout(function() {
promise.then(function(response) {
alert(response);
});
}, 1000)
As others have already pointed out, you can add callbacks with .then before or after the promise has been resolved, and you can even add more than one callback.
These callbacks will be called in the order they were added, but always asynchronously, after the current turn of the event loop. So if the promise has already been resolved when you add a .then, your handler will be called immediately, but in the "ascynchronous sense".
The Promises/A+ spec says:
[...] onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack.
A promise has state, which means that even after the promise gets fulfilled, you can attach callbacks using .then to it, and they will be called, with the same result as if the promise was fulfilled after they were attached.
Fulfilled is the final state of a successful promise. This means that you can attach more handlers to the fulfilled promise in the future, using the promise as a cache for the original response.
.then() on MDN
then()
Calls one of the provided functions as soon as this promise is either
fulfilled or rejected. A new promise is returned, whose state evolves
depending on this promise and the provided callback functions.
The appropriate callback is always invoked after this method returns,
even if this promise is already fulfilled or rejected. You can also
call the then method multiple times on the same promise, and the
callbacks will be invoked in the same order as they were registered.
The then callback will never get called before the promise is resolved, which is what I think you mean by complete. However, if a promise is resolved before it is returned from a function, any additional success callbacks chained after that moment will still be executed. For example,
function getMeAResolvedPromise() {
var prom = new Promise();
prom.resolve('some val');
return prom;
}
...
getMeAResolvedPromise.then(function(result) {
// this will still be executed
});
I would like to get a deeper understanding of how Promises work internally.
Therefore I have some sample code:
var p1 = new Promise(
function(resolve, reject) {
window.setTimeout(
function() {
resolve('res called')
}, 2000);
});
var p2 = new Promise(
function(resolve, reject) {
window.setTimeout(
function() {
resolve('res called')
}, 2000);
});
function chainPromises() {
return p1.then(function(val) {
console.log("p1");
return p2.then(function(val) {
console.log("p2");
return val;
});
});
}
chainPromises().then(function(val) {
console.log(val);
});
Here a link to execute this code.
As you would predict, first p1 is resolved, afterwards p2 and in the end the final then prints the resolv value.
But the API ref states the following:
"then" returns a new promise equivalent to the value you return from
onFulfilled/onRejected after being passed through Promise.resolve
So it would be interesting to know WHEN exactly the "then" function is executed?
Because the final "then" in the code is chained to the chainPromises(), I first thought that
it would execute after the function chainPromises() returns something (in this case another promise).
If this would have been the case the "val" of the final "then" function would be the returned promise.
But instead, the final "then" waits until all promises inside the first "then" which are returned have been resolved.
This absolutely makes sense because in this way, the "then" functions can be stacked, but
I do not really get how this is done, since the API spec. does not really cover what "then" returns and when the "then" functions is executed.
Or in other words, why does the final "then" function wait until all the Promises are resolved inside the chainPromises() function instead of just waiting for the first returned object as the API doc says.
I hope I could make clear what I mean.. :)
About Promise resolution
The thing you're witnessing here is called recursive thenable resolution. The promise resolution process in the Promises/A+ specification contains the following clause:
onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x)
The ES6 promise specification (promises unwrapping) contains a similar clause.
This mandates that when a resolve operation occurs: either in the promise constructor, by calling Promise.resolve or in your case in a then chain a promise implementation must recursively unwrap the returned value if it is a promise.
In practice
This means that if onFulfilled (the then) returns a value, try to "resolve" the promise value yourself thus recursively waiting for the entire chain.
This means the following:
promiseReturning().then(function(){
alert(1);
return foo(); // foo returns a promise
}).then(function(){
alert(2); // will only run after the ENTIRE chain of `foo` resolved
// if foo OR ANY PART OF THE CHAIN rejects and it is not handled this
// will not run
});
So for example:
promiseReturning().then(function(){
alert(1);
return Promise.resolve().then(function(){ throw Error(); });
}).then(function(){
alert("This will never run");
});
And that:
promiseReturning().then(function(){
alert(1);
return Promise.resolve().then(function(){ return delay(2000); });
}).then(function(){
alert("This will only run after 2000 ms");
});
Is it a good idea?
It's been the topic of much debate in the promises specification process a second chain method that does not exhibit this behavior was discussed but decided against (still available in Chrome, but will be removed soon). You can read about the whole debate in this esdiscuss thread. This behavior is for pragmatic reasons so you wouldn't have to manually do it.
In other languages
It's worth mentioning that other languages do not do this, neither futures in Scala or tasks in C# have this property. For example in C# you'd have to call Task.Unwrap on a task in order to wait for its chain to resolve.
Let's start with an easy perspective: "chainPromises" returns a promise, so you could look at it this way:
// Do all internal promises
var cp = chainPromises();
// After everything is finished you execute the final "then".
cp.then(function(val) {
console.log(val);
});
Generally speaking, when returning a promise from within a "then" clause, the "then" function of the encapsulating promise will be marked as finished only after the internal "then" has finished.
So, if "a" is a promise, and "b" is a promise:
// "a"'s "then" function will only be marked as finished after "b"'s "then" function has finished.
var c = a.then(function () {
return b.then(function () {
console.log("B!");
};
};
// c is a promise, since "then" always returns a promise.
c.then(function() {
console.log("Done!");
};
So the output will be:
B!
Done!
Notice btw, that if you don't "return" the internal promise, this will not be the case:
// "a"'s "then" function will only be marked as finished without waiting for "b"'s "then" to finish.
var c = a.then(function () {
// Notice we're just calling b.then, and don't "return" it.
b.then(function () {
console.log("B!");
};
};
// c is a promise, since "then" always returns a promise.
c.then(function() {
console.log("Done!");
};
Here we can't know what would be outputted first. It could be either "B!" or "Done!".
Please check the below example regarding how promises works:
The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.
console.log('person1: shoe ticket');
console.log('person2: shoe ticket');
const promiseGirlFriendBringingTickets = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ticket');
}, 3000);
});
promiseGirlFriendBringingTickets.then((t) => {
console.log(`person3: show ${t}`);
})
console.log('person4: shoe ticket');
console.log('person5: shoe ticket');
Promise then return promise object, not promise's resolved value. I forked your JsFiddle, and added some of mine try this.
promise.then is executed right after that promise object is resolved.
I do not know how this is done in actual promises libraries, but I was able to re-create this functionality in the following way:
1) each promise has a waitingPromises property;
2) then method returns a new promise, and the original promise's waitingPromises property points to the new promise.
In this way, the chain of .then()s creates a structure that is similar to a linked list or rather a tree (each promise can have several waiting promises). A promise can be resolved only after its 'parent' promise has been resolved. The .then method itself is executed immediately, but the corresponding promise that it creates is resolved only later.
I am not sure this is a good explanation and would love to learn about other possible approaches.
Normally code is synchronous - one statement executes like (fileopen) and there is a guarantee that the next statement will execute immediately afterwards like filewrite()
but in asynchronous operations like nodejs, you should assume that
you have no idea when the operation will complete.
You can't even assume that just because you send out one request first, and another request second, that they will return in that order
Callbacks are the standard way of handling asynchrnous code in JavaScript
but promises are the best way to handle asynchronous code.
This is because callbacks make error handling difficult, and lead to ugly nested code.
which user and programmer not readble easily so promises is the way
You can think of Promise as a wrapper on some background task. It takes in a function which needs to be executed in the background.
The most appropriate place to use a promise is where some code is dependent on some background processing and it needs to know the status of the background task which was executed. For that, the background task itself accepts two callback resolve and reject in order to convey its status to the code which is dependent on it. In layman terms, this code is the one behind it in the promise chain.
When a background task invokes resolve callback with some parameter. it's marking the background operation successful and passing the result of the background operation to the next then block which will be executed next. and if it calls reject, marking it as unsuccessful then the first catch block will be executed.
In your custom promise, you can pass an error obj to the reject callback so that next catch block is aware of the error happened in the background task.