节点和异步/等待,承诺......哪种解决方案最好?

时间:2016-02-05 13:28:18

标签: javascript node.js asynchronous promise

使用Node和Express with Babel并尝试找出async / await和promises之间的最佳方法。

关键要求:

  • 能够传递我自己的错误
  • 不会造成阻碍
  • 以更多的ES6 / ES7方式解决问题

我出来了:

承诺:

loadByIdPromises: function (req, res, next, _id) {
  console.log('loadByIdc: ', _id);
  Artwork.loadById( { _id } )
    .then( (artwork) => {
      req.artwork = artwork;
      next();
    })
    .catch( (err) => next(new NoDataError('cannot find by ID')));
}

异步/等待:

loadByIdAsync: async function (req, res, next, _id) {
  console.log('loadByIdb: ', _id);
  try {
    req.artwork = await Artwork.loadById( { _id } );
    next();
  } catch (err) {
    next(new NoDataError('cannot find by ID'));
  }
}

或Async / Await with wrapper

let wrap = fn => (...args) => fn(...args).catch(args[2]);
loadByIdAsyncWrap: wrap( async function (req, res, next, _id) {
  console.log('loadByIda: ', _id);
  req.artwork = await Artwork.loadById( { _id } );
  next();
}),

承诺似乎很干净,但当事情变得复杂时可能导致层叠。但是有一个漂亮而干净的错误处理。

Async / Await似乎很干净,但是我无法弄清楚如何从等待整个try / catch之外的方式抛出错误。

Async / Await with wrapper看起来很简单(至少在这种情况下 - node express router)处理错误(但没有可能设置我自己的)。但是包装器特定于req,res,next params,在我看来它是外来的东西(比如我们的css2 / 3幸福之前的html中的额外div)。

选择哪种方法?谢谢你的建议。

1 个答案:

答案 0 :(得分:1)

我会使用Promise方法,因为async / await并非接近主流。

但是我发现一个潜在的问题是,您next()的调用 初始块意味着您可以成功完成第一阶段,然后调用next(),但是然后如果 抛出一个未被捕获的错误,调用堆栈将返回一个级别,该错误被第一个.catch()块捕获。然后,即使真正的错误出现在cannot find by ID处理程序中,您也会生成next()错误。

我建议这样做,而不是:

function (req, res, next, _id) {
  console.log('loadByIdc: ', _id);
  Artwork.loadById( { _id } )
    .then((artwork) => req.artwork = artwork)
    .then(next, (err) => next(new NoDataError('cannot find by ID')));
}

这仍然会让您遇到.catch如何next可能由nums = [41.25, 38.75, 43.25, 37.25, 37.5, 43.75] sats = [G01, G03, G04, G11, G28, G32] 抛出的异常的问题,但至少您不会被捕获该异常的点误导。