2016-02-05 75 views
-1

与Babel一起使用Node和Express并试图找出异步/等待和承诺之间的最佳方法。节点和异步/等待,承诺...哪个解决方案最好?

主要要求:

  • 能够通过我自己的错误
  • 不会造成阻塞
  • 来解决这个问题更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')); 
    } 
} 

或异步/等待与包装

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

承诺似乎是干净的,但可能会导致级联当事情复杂。但有一个很好,干净的错误处理。

异步/等待看起来很干净,但我无法弄清楚如何从整个try/catch的事情等待其他方式抛出错误。

异步/等待与包装看起来很简单,并且(至少在这种情况下 - 节点快速路由器)处理错误(但没有可能设置我自己的)。但包装是特定于请求,水库,下一个参数,在我看来是外来的东西(比如我们的css2/3幸福之前的html中额外的div)。

什么方法可供选择?感谢您的建议。

+0

你看看koa:https://github.com/koajs/koa? –

+0

你在基于Promise的版本中可能存在潜在的问题,也许在其他版本中可能存在问题 - 在调用next()时引发的任何异常都可能最终传播回链。你可能想要'load()。then(do_stuff).then(next,(err)=> next(new Error))' – Alnitak

+1

使用'try' /'catch'进行错误处理有什么问题? –

回答

1

我会使用Promise方法,因为async/await还没有接近主流。

但是我看到一个潜在的问题,即你的next()调用是初始块的含义,你可以有一个成功的第一阶段,然后调用next(),但这时如果抛出一个错误,是不是抓住了调用堆栈将回升到一个水平,这个错误被第一个.catch()块所捕获。即使真正的错误出现在next()处理程序中,您也会生成cannot find by ID错误。

我建议这个,而是:

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被抛出的异常的问题,但至少你不会被点误导在那个例外被捕获。

+0

错误处理方面对我来说是新的,谢谢@Alnitak。我会upvote你的答案,但我不能。 – DavidC

+0

*“这仍然会给你带来一个问题,就是如何捕获'next'可能抛出的任何异常。”*它会被'then'返回的promise中被捕获并被拒绝。上面的代码应该处理拒绝(通过'.catch(err => ...)')或者将承诺链传递给某些确实的东西。最简单的方法(如果不传递它)是将传递给最后一个'.then'的第二个处理程序移动到后续的'.catch'中,以处理由'next'引发的拒绝。 (cc @DavidC) –

+0

@ T.J.Crowder随时更新,如果你喜欢 – Alnitak