How to convert a callback code to promise in ES6

This question already has an answer here:

  • How do I convert an existing callback API to promises? 17 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.


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

    记住“.then”和“.catch”是异步的。


    This is an important topic. For the sake of functional coding in a synchronous looking manner the point of using promises is to move the logic in the callback to the then stage. So although you could you shouldn't handle the logic within the promise itself but at the then stage. This way of thinking helps us to create a general purpose promisify utility function which works for all certain type callback structures. In your case the callback type is the Node standard error first type. So as per your code 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);
      }
    };
    

    a general promisfy function should works as follows;

    var moduleExports = (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);
      }
    };
    
    function promisfy(fun, ...args){
      return new Promise((v,x) => fun(...args, (err,data) => !!err ? x(err) : v(data)));
    }
    
    var p = promisfy(moduleExports,4,5);
    p.then(val => console.log(val,val.area(),val.perimeter()), err => console.log(err));
    
    // p.then(val => callback(null,val), err => callback(err))
    链接地址: http://www.djcxy.com/p/55524.html

    上一篇: Node.JS异步/等待处理回调?

    下一篇: 如何将回调代码转换为ES6中的承诺