News for hackers. Stuff that matters.
Re:Never Mix Promises and Callbacks in NodeJS by mattnewton on Friday April 07, 2017 @10:18AM (#14059809)
Why was the solution to fallback to callbacks instead of just using promises all the way through? (Edit, removed mention of bluebird that would not have helped)

The problem here isn't that they are being swallowed, it is that the tests have a constraint that the callback be called only once, which is conveniently the behavior of a then applied to the promise you would return.

Re:Never Mix Promises and Callbacks in NodeJS by partisan on Friday April 07, 2017 @10:41AM (#14060032)
I agree. I don't think the headline of this article is correct. The author's expectations were incorrect and it certainly is a good thing for everyone to be aware of, but this is like saying "don't use pointers because I didn't release memory and it caused a memory leak".

If you are using promises, understand how they work. The same for callbacks.

Re:Never Mix Promises and Callbacks in NodeJS by jvranish42 on Friday April 07, 2017 @10:53AM (#14060154)
I'm the author of that post. I could have certainly used promises all the way through, and in some cases that might be the better option.

My example is contrived, but in the larger project that I was working in, almost all of the existing code used callbacks. Refactoring all that code to use promises, just to accommodate the two or three places that actually needed them, probably would not have been worth it.

Re:Never Mix Promises and Callbacks in NodeJS by spankalee on Friday April 07, 2017 @12:38PM (#14061206)
It is worth it though because of the much better error handling in Promises and the ability to use async/await which makes error handling even more easy to get correct.

I'd suggest making all functions that take callbacks also return Promises to make the transition easier:

    async function fetchFirstUser(iswhatIwant, callback) {
      const safeCallback = (user) => {
        try {
          callback(user);
        } catch (e) {
          console.error(e);
        }
      };

      try {
        const user = await knex.first().from("users");
        safeCallback(user);
        return user;
      } catch (e) {
        safeCallback(null);
        throw e;
      }
    }
You can put this in a utility (and I'd recommend standardizing on Node's callback style):

    async doWithCallback(promise, callback) {
      const safeCallback = (error, result) => {
        if (callback == null) {
          return;
        }
        try {
          callback(null, result);
        } catch (e) {
          console.error(e);
        }
      };
      try {
        const result = await promise;
        safeCallback(null, result);
        return result;
      } catch (e) {
        safeCallback(e);
        throw e;
      }
    }

    async function fetchFirstUser(iswhatIwant, callback) {
      return doWithCallback(knex.first().from("users"), callback);
    }
At some point you can start warning when callbacks are passed in, then throwing, then remove the argument.
Re:Never Mix Promises and Callbacks in NodeJS by vkjv on Friday April 07, 2017 @12:25PM (#14061068)
You don't need to refactor the existing code. You can change the calling code.

    // Promisifying a standard callback
    const myAsyncMethod = Bluebird.promisify(myCallbackMethod);

    // Or if you have weird callback passing and need
    // to manipulate the callback method being passed around
    function myAsyncMethod(...args) {
        return Bluebird.fromCallback(cb => myAsyncMethod(cb, ...args));
    }