从中间件中的Promise调用"next()"会导致“下一个不应被多次调用" [英] Calling 'next()' from promises in a middleware causes 'next shouldn't be called more than once'
问题描述
最近,我将代码从Express更改为Restify.老实说,我不确定它以前是否曾经发生过,但我想确实是这样.
基本上,在我的中间件中,我调用一个承诺方法,当它解析后,我调用next
,并在下一个中间件中执行其他操作.当它被拒绝时,在某些情况下,我也想正确地调用next
.否则,它必须调用将err
传递给next
的错误中间件.
somePromise()
.then(()=>{
next();
})
.catch((err)=>{
if(err.someatt) next();
else next(err)
});
它可以很好地与somePromise
的预期结果一起使用.问题是next
受then-catch
链约束.并且在下一个中间件中引发错误时,它会调用catch
方法并再次调用next
!
我发现next具有属性called
,并且在再次调用next之前将其设置为false时,我摆脱了错误.但这当然是一种反模式.而且我在另一个也使用了promises的中间件中遇到了同样的问题(按预期方式调用next
,然后在catch
语句中再次调用它).
还有其他人有这样的问题吗?
将您的链更改为此:
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
});
.catch()
回调,但仅针对链中上级引发的错误而调用,而不针对相邻的.then()
回调中引发的错误而调用.
从这个很棒的答案借来的非常有用的流程图说明了.then(onFulfilled, onRejected)
和.then(onFulfilled).catch(onRejected)
之间的区别:>
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?
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)
:
这篇关于从中间件中的Promise调用"next()"会导致“下一个不应被多次调用"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!