×
Table of Contents
About Promise
How Promises Work
A promise is an object which can be returned synchronously from an asynchronous function.
It will be in one of 3 possible states:
- Fulfilled: onFulfilled() will be called (e.g., resolve() was called)
- Rejected: onRejected() will be called (e.g., reject() was called)
- Pending: not yet fulfilled or rejected
Promises following the spec must follow a specific set of rules:
- A promise or “thenable” is an object that supplies a standard-compliant .then() method.
- A pending promise may transition into a fulfilled or rejected state.
- A fulfilled or rejected promise is settled, and must not transition into any other state.
- Once a promise is settled, it must have a value (which may be undefined). That value must not change.
- A Promise can be resolved or rejected, exclusively and only once.
- A call to promise.then returns a promise, so that we can call the next promise
- A value returned by a .then handler is immediately passed to the next handler
- If the returned value is a promise, then the further execution is suspended until it settles.
- A fetch() promise will reject with a TypeError when a network error is encountered or CORS is misconfigured on the server side
- By default, fetch won’t send or receive any cookies from the server
Chained Promises
Chained Promises Sample
function testMe(myUrl, test, dataError) {
dumpMessage("Testing Promise Chaining: " + test, false);
let url = myUrl;
fetch(url) // fetch returns a promise
.then(response => { // Our Success Handler returns response Object
if(response.ok) {
if ( dataError) { // Just for testing - Mimicking a Data Proessing Error
throw new Error('Data Processing Error');
}
return response.json();
}
throw new Error('Network response was not ok at Chain Level 1');
}) // Catches Exception for our Success Handler and for our Reject Handler
.catch(e => {
dumpMessage("Exception at Chain Level 1 : " + e,true );
throw new Error('Initial Fetch failed for URL: ' + url);
})
.then(jsonData => { dumpMessage("ID: " + jsonData.id + " - name : " + jsonData.name,false ); return(jsonData.name);} )
.then( (user) => { dumpMessage("Username: " + user, false); return fetch("https://api.github.com/users/"+user ); })
// Load the response as json
.then(response => response.json())
// Show the avatar image (githubUser.avatar_url) for 3 seconds (maybe animate it)
.then(githubUser => {
dumpMessage("Displaying Github Avatar Image for 3 seconds!", false);
let img = document.createElement('img');
img.src = githubUser.avatar_url;
img.className = "promise-avatar-example";
document.body.append(img);
setTimeout(() => {
img.remove();
dumpMessage("Removed Github Avatar Image !", false);
}, 3000); // (*)
})
.catch(err => { // Catch all Hanlder return true/false for retry logic
dumpMessage("CatchAll Error-handler: " + err, true);
});
}
Promises and Error Handling
Overview
| Pomisess Error Handling Diagram |
|---|
Handle Errors – Pattern 1
save().then(
handleSuccess,
handleError
);
- Problem Exceptions in handleSuccess() are not catched
Handle Errors – Pattern 2
save()
.then(handleSuccess)
.catch(handleError)
Sample:
fetch(url) // fetch returns a promise
.then(response => { // Our Success Handler returns response Object
if(response.ok) {
if ( dataError) { // Just for testing - Mimicking a Data Proessing Error
throw new Error('Data Processing Error');
}
return response.json();
}
throw new Error('Network response was not ok at Chain Level 1');
}) // Catches Exception for our Success Handler and for our Reject Handler
.catch(e => {
dumpMessage("Exception at Chain Level 1 : " + e,true );
throw new Error('Initial Fetch failed for URL: ' + url);
})
.then(jsonData => { dumpMessage("ID: " + jsonData.id + " - name : " + jsonData.name,false ); return(jsonData.name);} )
...
- Handles both Processing Errors and Network Errors
- CodePen Project: Press Invalid URL & Data Error Button
Handle Errors – Pattern 3
save()
.then(
handleSuccess,
handleNetworkError -> Handle and Fix Network Error
)
.catch(handleProgrammerError) -> Handle anf Fix ProgamError in handleSucessFunction
Sample:
fetch(url)
.then(response => { // Our Success Handler
if(response.ok) {
if ( dataError) { // Mimicking a Data Proessing Error
throw new Error('Data Processing Error');
}
return response.json();
}
throw new Error('Network response was not ok.');
},
err => { // Now we handle the error (rejection reason)
dumpMessage("Handle error (rejection reason): " + err,true );
// Create a Dummy object
dumpMessage("Create a Default Object to Finish Promise Chain");
myObj = { "name":"hhutzler", "id":999 };
return myObj;
} )
.catch(e => { dumpMessage("Processing Error Chaining at Level 1 : " + e,true );
dumpMessage("Create a Default Object to Finish Promise Chain");
myObj = { "name":"hhutzler", "id":999 };
return myObj;
})
// , // Now we handle the error (rejection reason)
//e => { dumpMessage("Initial Fetch Error: " + e,true ); throw new Error('Initial Fetch Error for URL' + url); } )
//.then(response => response.json() )
.then(jsonData => { dumpMessage("ID: " + jsonData.id + " - name : " + jsonData.name,false ); return(jsonData.name);} )
....
- Allows us to handle Network errors and Program Errors individually
- CodePen Project: Press FIX Invalid URL & FIX Data Error Button