Calling 'next()' from promises in a middleware causes 'next shouldn't be called more than once'

末鹿安然 提交于 2019-12-24 08:47:25

问题


Recently I changed my code from Express to Restify. I'm honestly not sure if it used to happen before, but I guess it did.

Basically in my middleware I call a promisified method and when it resolves I call next and do other stuff in the next middleware. When it is rejected I also want to call next with no errors in some cases. Otherwise it must call the error middleware passing err to next.

somePromise()
.then(()=>{
    next();
})
.catch((err)=>{
    if(err.someatt) next();
    else next(err)
});

It works fine with the expected results of somePromise. The problem is that next is bound by the then-catch chain. And when an error is thrown in the next middleware it invokes the catch method and calls next again!

I found out that next has an attribute called and when I turn it to false before calling next again I get rid of the the errors. But of course it is an antipattern. And I'm having the same problem in a different middleware that I also used promises (calling next as expected and then calling it again in the catch statement).

Anyone else had a problem like that?


回答1:


Change your chain to this:

somePromise().then(() => {
  next();
}, err => {
  // error occurred in somePromise()
  if(err.someatt) next();
  else next(err);
}).catch(err => {
  // error occurred in .then()'s next()
  // don't call next() again
});

The optional second argument of .then() acts as a .catch() callback, but is only invoked for errors thrown higher up in the chain, and is not invoked for errors thrown in the adjacent .then() callback.

A very helpful flowchart borrowed from this awesome answer demonstrates the difference between .then(onFulfilled, onRejected) and .then(onFulfilled).catch(onRejected):



来源:https://stackoverflow.com/questions/48590754/calling-next-from-promises-in-a-middleware-causes-next-shouldnt-be-called

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!