如何在 ES6 中将回调代码转换为 Promise

Kul*_*ear 5 javascript asynchronous callback promise ecmascript-6

我正在学习 ES6 标准,所以我从一个非常基本的示例代码开始。

JavaScript 中存在回调地狱,所以这次我确实想避免使用回调。但我遇到了一个问题,我真的不知道如何将回调样式代码转换为承诺。

例如,如果我有这样的代码如下所示

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);
  }
};
Run Code Online (Sandbox Code Playgroud)

ES6 中如何将其转换为 a Promise?这是一种将回调转换为承诺的推荐行为吗?

我已经读过这个例子,但实际上我对结果感到困惑。我认为在开始重写对 Promise 的回调之前,我需要首先了解这一点。

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

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

console.log('Hi!');

// Promise
// Hi!
// Resolved 
Run Code Online (Sandbox Code Playgroud)

我的理解是Promise创建后立即运行。但不知道为什么thenmethod中的代码会最后运行。

sdg*_*uck 2

现有的答案成为延迟反模式的牺牲品。我会避免这种方法,因为它不必要地冗长,并且没有利用完整的 Promise API。另一个答案是使用承诺。实际上,只有当您无法更改使用回调样式编写的代码(例如使用第三方脚本)时,才需要使用承诺。

您问了两个问题,第二个问题是为什么 Promise 的行为方式与您在给定示例中看到的方式相同。为了找到这个问题的答案,我建议您使用有关此类性质的许多现有问题。例如,Promise 不就是回调吗?

至于你的第一个问题,即如何重构代码以使用 Promises,这是我的建议:

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."
  })
Run Code Online (Sandbox Code Playgroud)

由于函数本身并不依赖于异步操作的完成,因此我们可以使用辅助方法Promise#resolvePromise#reject从函数返回一个 Promise,表示创建“矩形”对象的成功或失败。它们会产生一个新的 Promise,其状态分别为已解决或拒绝,并带有值或错误。