Reputation: 875
I am confused with below simple Promise example.
Question 1: From the console log, why the resolve is executed after the console.log("200") statement?
Question 2: Enable the resolve() before onload() and make the GET request against with an invalid url. Even the AJAX returned with 404, the reject won't be called this time since the resolve before onload is called. Why won't reject be called ?
https://jsfiddle.net/tut5va0m/3/
function get(url) {
// Return a new promise.
return new Promise(function(resolve, reject) {
// Do the usual XHR stuff
var req = new XMLHttpRequest();
req.open('GET', url);
//Enable below for Question 2
//resolve(req.response);
req.onload = function() {
// This is called even on 404 etc
// so check the status
if (req.status == 200) {
//Question 1
resolve(req.response);
console.log("200");
}
else {
// Otherwise reject with the status text
// which will hopefully be a meaningful error
reject(Error(req.statusText));
}
};
// Handle network errors
req.onerror = function() {
reject(Error("Network Error"));
};
// Make the request
req.send();
});
}
function resolve(data) {
console.log("Success!!! " + data);
}
function reject(data) {
console.log("Fail!!! " + data);
}
var url = '/echo/json';
var invalidUrl = '/abc'
get(url).then(resolve, reject);
//below is for Question 2
get(invalidUrl).then(resolve, reject);
Upvotes: 1
Views: 4519
Reputation: 5769
Promises are generally used for asynchronous operations, so a line that follows a promise operation (such as .then
) will execute before the promise handler is executed. This is behavior that should familiar to you if you're use to callback functions, such as the code wrapped in your req.onload
function. With your code, what you're seeing is the Promise.resolve
executing, then the console.log
, then anything chained to the Promise which in your case has the confusing names resolve
and reject
as registered on this line:
get(url).then(resolve, reject);
It would be more clear to rename those function afterResolve and afterReject because that's when those function execute. If you want to make sure the console.log
is executed after the promise is resolved or rejected, you need to put that statement inside of those promise-handling function, or chain another function on and do it there.
get(url).then(resolve, reject).then(function(){
console.log('It worked')
})
As for your second question, a promise can only be resolved or rejected once. You can't resolve it multiple times, nor can you reject it after it's been resolved. That promise has done its duty after it's been resolved or rejected and calling those functions won't do anything afterwards. You'll need to create new promises after that.
get(url).then(function successFirstRequest(){
return get(someOtherUrl)
}).then(function successSecondRequest(){
alert('Completed two network requests')
}).catch(err){
// one of your requests failed
})
Upvotes: 2
Reputation: 5519
For Question A, resolve use process.nextTick(), so it's possible that current function will finish before resolve callback will be called. It's the reason why you see "200" before "Success"
For question B, a Promise can't be both resolved and rejected. You have to choose or operation succeed and is resolved or it failed and it's rejected. It's can be both.
Upvotes: 2