Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a callback code to promise in ES6 [duplicate]

I am learning the ES6 standard so I start from a very basic example code.

There are callback hells exist in JavaScript so this time I do want to avoid using callbacks. But I met a problem that I don't really know how to convert a callback style code to a promise.

For example, if I have such code looks like below

module.exports = (x, y, callback) => {
  try {
    if (x < 0 || y < 0) {
      throw new Error('Rectangle dimensions are wrong.');
    } else {
      callback(null, {
        perimeter() {
          return (2 * (x + y));
        },
        area() {
          return (x * y);
        },
      });
    }
  } catch (error) {
    callback(error, null);
  }
};

How should I convert it to a Promise in ES6? Is that a kind of recommended behavior that convert callbacks to promises?

I have read this example but I was actually confused by the result. I think before I start to rewrite my callbacks to promises I need to understand this first.

let promise = new Promise(function(resolve, reject) {
  console.log('Promise');
  resolve();
});

promise.then(function() {
  console.log('Resolved.');
});

console.log('Hi!');

// Promise
// Hi!
// Resolved 

My understanding is that Promise runs immediately after getting created. But I don't know why the code in then method will be run last.

like image 453
Kulbear Avatar asked Nov 08 '22 10:11

Kulbear


1 Answers

The existing answers fall prey to the deferred anti-pattern. I would avoid this approach as it is unnecessarily verbose and doesn't take advantage of the full Promise API. Another of the answers uses promisification. It's really only necessary to use promisification when you are not able to change the code that is written using the callback-style, for example with third-party scripts.

You are asking two questions, the second of which is why do Promises behave the way that you have seen in your given example. To find answers to this question I suggest you use the many existing questions on SO of this nature. For example, aren't Promises just callbacks?

As for your first question, of how to refactor your code to use Promises, here is my suggestion:

module.exports = (x, y) => {
  if (x < 0 || y < 0) {
    return Promise.reject(new Error('Rectangle dimensions are wrong.'));
  } else {
    return Promise.resolve({
      perimeter() {
        return (2 * (x + y));
      },
      area() {
        return (x * y);
      },
    });
  }
};

// e.g. success
createRectangle(10, 10)
  .then(rect => {
    console.log(rect.area()) //=> 100
  })

// e.g. failure
createRectangle(-1, -1)
  .catch(err => {
    console.log(err) //=> "Error: Rectangle dimensions are wrong."
  })

As the function doesn't itself depend on the completion of an asynchronous operation we can use the helper methods Promise#resolve and Promise#reject to return a Promise from the function that represents the success or failure of creating the "rectangle" object. These produce a new Promise whose status is resolved or rejected with either a value or an error, respectively.

like image 128
sdgluck Avatar answered Nov 14 '22 23:11

sdgluck