The question is published on by Tutorial Guruji team.
I am confused with the use of promise, specifically of its way of data manipulation (passing values from block to block) and exception handling (bubbling up the error). I am trying to learn a right way to use promise and to handle error, something like
Error: A caught error. at promiseTwo() at promiseOne() at subprocess() at mainprocess()
Here are my two attempts in implementing them:
Attempt 1: Clumsy, deeply nested, and errors are uncaught.
var subprocess = () => { return new Promise((resolve, reject) => { promiseOne().then(data1 => { // Some code with data1, throw some error promiseTwo().then(data2 => { // Some code with data1n2, throw some error promiseThree().then(data3 => { // Data manipulation with data1, data2, and data3 return resolve(<...>) }).catch(err3 => { throw err3 }) }.catch(err2n3 => { throw err2n3 }) // >>> ERR: Cannot get err3. }.catch(err1n2n3 => { return reject(err1n2n3) }) // >>> ERR: Cannot get err3 or err2. } } return new Promise((resolve, reject) => { subprocess().then(data => { // TODO }).catch(allErr => { return reject(allErr) } }
Attempt 2: Unable to use data from previous promise block.
var subprocess = () => { return new Promise((resolve, reject) => { promiseOne() .then(data1 => { // Some code with data1, throw some error return promiseTwo() }) .then(data2 => { // Some code with data1n2, throw some error // >>> ERR: Cannot get data1 return promiseThree() }) .then(data3 => { // Data manipulation with data1, data2, and data3 // >>> ERR: Cannot get data1 and data2 return resolve(<...>) }) .catch(err1n2n3 => { return reject(err1n2n3) }) } } return new Promise((resolve, reject) => { subprocess().then(data => { // Some code, throw some error }).catch(allErr => { return reject(allErr) } }
Note: Some of the promise block (i.e. promiseOne
, promiseTwo
, etc.) are pre-defined so I do not have control over what data they will return. I am sure there are more errors in the attempts (e.g. if return
ing a function is a right way to do it).
Please help. Thanks.
Answer
for this kind of situation, you can combine promises and async-await together.
From the question, it seems we have three promises and one function that executes and handle them.
You can try something like this –
const subProcess = () => { return new Promise((resolve, reject) => { // Using IIFE ( You shouldn't put async keyword on promise callbac ) (async () => { // Use of try catch to handle the errors try { await promiseOne() await promiseTwo() await promiseThree() // Additional code if need after them } catch(err){ // Handle error ( all three promise error will be transferred here ) } })() }) }
The above code waits for the promises to execute one by one and also catch error from all three promises if any.
And as @samuei mentioned, you can also use Promise.all() in this.
const subProcess = () => { return new Promise((resolve, reject) => { // Using IIFE ( You shouldn't put async keyword on promise callbac ) (async () => { // Use of try catch to handle the errors try { const myPromises = [promiseOne, promiseTwo, promiseThree]; const res = await Promise.all(myPromises); // Additional code if need after them } catch(err){ // Handle error ( all three promise error will be transferred here ) } })() }) }
And if you don’t want to use async-await then you can do something like this as well
const subProcess = () => { return new Promise((resolve, reject) => { const myPromises = []; const myPromises = [promiseOne, promiseTwo, promiseThree]; Promise.all(myPromises) .then(res => { // Handle the response }) .catch(err => { // Handle the error }) }) }