Improved way to deal with callbacks inside promises

Improved way to deal with callbacks inside promises



I have the following code that uses callbacks inside promises:


callbacks


promises


const clue = 'someValue';

const myFunction = (someParam, callback) =>
someAsyncOperation(someParam) // this function returns an array
.then((array) =>
if (array.includes(clue))
callback(null, array); // Callback with 'Success'

else
callback(`The array does not includes: $clue`); // Callback with Error

)
.catch((err) =>
// handle error
callback(`Some error inside the promise chain: $err`) // Callback with Error
)



and call it like this:


myFunction (someParam, (error, response) =>
if(error)
console.log(error);

else
// do something with the 'response'

)



Reading some documentation, I found that there is some improved way to do this:


const myFunction = (someParam, callback) =>
someAsyncOperation(someParam) // this function returns an array
.then((array) =>
if (array.includes(clue))
callback(array);

else
callback(`The array does not includes: $clue`);

, (e) =>
callback(`Some error happened inside the promise chain: $e`);
)
.catch((err) =>
// handle error
callback(`Some error happened with callbacks: $err`)
)



My question:



In the sense of performance or best practices, it's okay to call the 'callback' function inside the promise as the two ways show or I'm doing something wrong, I mean some promise anti-pattern way ?


'callback' function





Pretty sure you should not have both an error handler (as the second argument to .then) and a catch. It's probably better to have only a single catch.
– CertainPerformance
Sep 2 at 23:23


.then


catch


catch





Also note that your second code, during success, is calling callback with array as the first argument (the error) rather than the second argument (the response).
– CertainPerformance
Sep 2 at 23:25


callback


array


error


response





Don't use callbacks inside of promises - that is an anti-pattern. Just return a promise and let the promise handle the notificaiton of completion or error. That's what they are designed for. The caller will then use .then() and .catch() on the returned promise instead of a callback. This is the current state and future of Javascript.
– jfriend00
Sep 2 at 23:45



.then()


.catch()





Don't unpromisify!
– Roamer-1888
Sep 3 at 1:00





@robe007 - Per your request, I added an answer to illustrate.
– jfriend00
Sep 3 at 2:39




2 Answers
2



This seems really backwards and takes away from the benefits of promises managing errors and passing them down the chain



Return the asynchronous promise from the function and don't interrupt it with callbacks. Then add a catch at the end of the chain


const myFunction = (someParam) =>
// return the promise
return someAsyncOperation(someParam) // this function returns an array
.then((array) =>
return array.includes(clue) ? array : ;
);


myFunction(someParam).then(res=>
if(res.length)
// do something with array
else
// no results

).catch(err=>console.log('Something went wrong in chain above this'))





This answer and jfriend00's answer are very good explained, but I select this becasue was the first. I can say that today I have learned again !
– robe007
Sep 3 at 4:21



jfriend00's



Do not use callbacks from inside of promises, that is an anti-pattern. Once you already have promises, just use them. Don't "unpromisify" to turn them into callbacks - that's moving backwards in code structure. Instead, just return the promise and you can then use .then() handlers to set what you want the resolved value to be or throw an error to set what you want the rejected reason to be:


.then()


const clue = 'someValue';

const myFunction = (someParam) =>
return someAsyncOperation(someParam).then(array =>
if (!array.includes(clue))
// reject promise
throw new Error(`The array does not include: $clue`);

return array;
);



Then, the caller would just do this:


myFunction(someData).then(array =>
// success
console.log(array);
).catch(err =>
// handle error here which could be either your custom error
// or an error from someAsyncOperation()
console.log(err);
);



This gives you the advantage that the caller can use all the power of promises to synchronize this async operation with any others, to easily propagate errors all to one error handler, to use await with it, etc...


await





It is possible also to add a catch statement to someAsyncOperation right?
– robe007
Sep 3 at 3:28


catch


someAsyncOperation





@robe007 - Yes, but there is no need unless you want to "handle" that error locally and not let the caller see that error directly. If the someAsyncOperation() promise rejects, then your .then() will not be called and the caller will directly see the rejected promise and their own .catch() which they already need to have will see the error.
– jfriend00
Sep 3 at 3:41


someAsyncOperation()


.then()


.catch()



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Some of your past answers have not been well-received, and you're in danger of being blocked from answering.



Please pay close attention to the following guidance:



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)