javascript - 如何将回调代码转换为 ES6 中的 promise

标签 javascript asynchronous callback promise ecmascript-6

<分区>

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

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

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

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);
  }
};

我应该如何将它转换为 ES6 中的 Promise?这是一种将回调转换为 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 

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

最佳答案

现有答案成为 deferred anti-pattern 的牺牲品.我会避免这种方法,因为它不必要地冗长并且没有利用完整的 Promise API。另一个答案使用 promisification。只有当您无法更改使用回调样式编写的代码(例如使用第三方脚本)时,才真正需要使用 promisification。

您在问两个问题,第二个问题是为什么 Promises 的行为方式与您在给定示例中看到的方式相同。要找到这个问题的答案,我建议您使用关于这种性质的 SO 的许多现有问题。例如,aren't Promises just callbacks?

关于您的第一个问题,即如何重构您的代码以使用 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."
  })

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

关于javascript - 如何将回调代码转换为 ES6 中的 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38939130/

相关文章:

javascript - 使用javascript向表中添加新行

javascript - 我应该如何循环依赖于前一个循环值的异步函数?

javascript - 此回调函数未定义

ruby - 如何在事务中发生 DataMapper 回调?

javascript - 禁用 Angular 中的选择?

javascript - 多选复选框下拉菜单在选中和取消选中时调用事件

javascript - 找不到分组功能标题的样式

java - 时间密集型计算和 SWT

asynchronous - JAX-WS 逻辑处理程序和 SOAPHandler

java - 重用函数时使用什么模式