Anonymous Promises
javascript, promise, web
Solution
If you your use case is to wrap function execution with a promise (to catch errors) you could do something like the code below.
You only need 1 `catch` function to handle errors in the entire chain. Try removing the comments and see how it behaves.
See also the `promisify` function which provides a nicer API in my opinion.
function promiseThis(doThis, withThis, task) {
return new Promise((resolve, reject) => {
const result = doThis(withThis);
if (result) {
resolve(result)
} else {
reject(`can't do task: ${task}`)
}
})
}
function print(name) {
// throw Error('printing error!');
console.log(name);
return name;
}
function capitalizeName(name) {
// throw Error('error capitalizing?!');
return name.toUpperCase();
}
fetch('https://randomuser.me/api/')
.then(response => response.json())
.then(json => promiseThis(print, json.results[0].email))
.then(email => promiseThis(capitalizeName, email))
.then(email => promiseThis(print, email))
.then(() => promiseThis(print, 'I can ignore the incoming value'))
.catch(e => console.error(e))
// You can achieve a nicer API like this
function getEmail(json) {
return json.results[0].email
}
function promisify(f, ...args) {
return function(resolved) {
return new Promise((resolve, reject) => {
resolve(f.apply(null, [...args, resolved]))
})
}
}
fetch('https://randomuser.me/api/')
.then(response => response.json())
.then(promisify(getEmail))
.then(promisify(print))
.then(promisify(capitalizeName))
.then(promisify(print))
.then(promisify(print, 'I can ignore the incoming value'))
.catch(e => console.error(e))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Problem
So promises is fairly new to me but I love the idea. Previously... I have previously used this which simply returns the data only after file is read completely and works as intended: ``` function something{ for (var i = 0; i < files.length; i++) { //push to the array promises.push(readFile(files[i])); } //use reduce to create a chain in the order of the promise array promises.reduce(function (cur, next) { return cur.then(next); }, Promise.resolve()).then(function () { //all files read and executed! }).catch(function (error) { //handle potential error }); } function readFile(file) { return new Promise(function (resolve, reject) { var reader = new FileReader(); reader.onload = function (progressEvent) { loadGeoJsonString(progressEvent.target.result, file.name); resolve(); } reader.onerror = function (error) { reject(error); } reader.readAsText(file); }); } ``` Currently I want to redo this by using ",then" and ".catch" to handle success and non-successes. In my current solution (Google Maps API for clarification but is irrelevant) I want to promise a function without returning a promise in the original function. This is what I have: ``` //create infobox object on marker function createInfobox(lat, lng) { var pos = new G.LatLng(lat, lng); promiseThis(dropMarker, pos, 'drop marker') .then(promiseThis(getGeocodeResult, pos, 'get address')) .catch(reason => {alert(reason)}) .then(promiseThis(isDeliverable, pos, 'determine deliverable status')) .catch(reason => {alert(reason)}) .then(promiseThis(getStores, pos, 'find stores')) .catch(reason => {alert(reason)}); } //handle promises function promiseThis(doThis, withThis, task) { return new Promise(function (resolve, reject) { var result = doThis(withThis); if (result) { resolve(result); } else { reject('Unable to ' + task); } }); } //drop marker on location function dropMarker(location) {..} //return object //get geocode results function getGeocodeResult(latlng) {..} //return string ``` In the end I would like to keep the results from each promise in an array and use it later. At the moment the getGeocodeResult just returns 'Unable to get address' immediately (also as a console error, not as an alert) What do I need to know about promises to make this work?