Search code examples
javascriptcallbackpromisees6-promiseasynccallback

Improved way to deal with callbacks inside promises


I have the following code that uses callbacks inside 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 ?


Solution

  • 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'))