Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在下一步之后使用Express js middleware res.locals_Javascript_Node.js_Express_Middleware - Fatal编程技术网

Javascript 在下一步之后使用Express js middleware res.locals

Javascript 在下一步之后使用Express js middleware res.locals,javascript,node.js,express,middleware,Javascript,Node.js,Express,Middleware,我实现了一个中间件(用于缓存),如下所示(从真实示例中可以看出): 从“快速异步处理程序”导入异步处理程序; 从“../cache”导入缓存; 导出异步函数缓存中间件(req、res、next){ //检查缓存中是否存在 res.locals.fromCache=cache.get(res.locals.params.cacheKey); //调用后续中间件,但不返回 next(); //在后续中间件链之后,如果需要,更新缓存 if(res.locals.accessgrated===true)

我实现了一个中间件(用于缓存),如下所示(从真实示例中可以看出):

从“快速异步处理程序”导入异步处理程序;
从“../cache”导入缓存;
导出异步函数缓存中间件(req、res、next){
//检查缓存中是否存在
res.locals.fromCache=cache.get(res.locals.params.cacheKey);
//调用后续中间件,但不返回
next();
//在后续中间件链之后,如果需要,更新缓存
if(res.locals.accessgrated===true){
set(res.locals.params.cacheKey,true);
}
}
导出默认asyncHandler(缓存中间件);
在随后的中间件中,我使用
res.locals.fromCache
来确定请求是否具有缓存值。那很好用

如您所见,我还希望在同一中间件中处理添加到缓存的过程。通过在
next
之后不返回,在中间件链完成后,调用堆栈将返回到此中间件以执行一些附加操作

让我吃惊的是,我希望
res.locals
是一个对象引用,因此在随后的中间件中所做的任何修改现在都可以在这里使用。如您所见,在本例中,我尝试访问
res.locals.accessgrated
(在后续中间件中设置),以确定是否需要更新缓存,但此范围内的
res.locals
上不存在此属性。这让我很惊讶,我想res一定是一个很深的副本


是否有进行此类操作的最佳实践,或者是否有任何理由不这样做?这似乎是一个整洁的解决方案(我在Python的类似框架中成功地使用了这种模式),而且比使用两个中间件来获取和设置缓存更可取。

好问题!就我个人而言,我认为这种方法可能会让你陷入困境,首先我会解释你遇到的问题,然后我会解释为什么我认为你应该改变一点方法

你看到的问题是比赛状态。在此特定实例中,
next()
是非阻塞的。上面写着“好了,我做完了,快车请继续”,快车继续它的快乐之路。如果将一些控制台日志添加到程序中,您会注意到调用
next()
之后的行可能是在以后的处理程序有时间完成之前执行的,特别是当它们对数据库或其他对象进行异步调用时

实际上,在下一个中间件完成之前,您正在运行if语句和cache.set,从而导致竞争条件

我不相信,尽管我最近没有检查,
next()
将允许您传递和接收回调,这意味着您最好将此中间件一分为二。我会让缓存检索作为第一个函数进行,然后调用其他中间件函数,最后调用一个进行缓存更新的函数。不要把中间件看作是一个模块,而更像是一个普通的旧函数,这比使用一个重载的中间件函数更有意义

所以现在你应该

fetchFromCache -> [various middleware, perhaps some hefty controllers] -> updateCache

好问题!就我个人而言,我认为这种方法可能会让你陷入困境,首先我会解释你遇到的问题,然后我会解释为什么我认为你应该改变一点方法

你看到的问题是比赛状态。在此特定实例中,
next()
是非阻塞的。上面写着“好了,我做完了,快车请继续”,快车继续它的快乐之路。如果将一些控制台日志添加到程序中,您会注意到调用
next()
之后的行可能是在以后的处理程序有时间完成之前执行的,特别是当它们对数据库或其他对象进行异步调用时

实际上,在下一个中间件完成之前,您正在运行if语句和cache.set,从而导致竞争条件

我不相信,尽管我最近没有检查,
next()
将允许您传递和接收回调,这意味着您最好将此中间件一分为二。我会让缓存检索作为第一个函数进行,然后调用其他中间件函数,最后调用一个进行缓存更新的函数。不要把中间件看作是一个模块,而更像是一个普通的旧函数,这比使用一个重载的中间件函数更有意义

所以现在你应该

fetchFromCache -> [various middleware, perhaps some hefty controllers] -> updateCache

我可以发誓我已经测试过了,但你完全正确。我刚刚测试了它,至少在Express4.x中,next没有返回任何东西(我希望得到一个承诺),所以目前我的做法根本不可行。我将切换到您提到的两个中间件解决方案作为我的后备方案。谢谢。@dpwrussell一点也不担心,我不知道express 5会带来什么,它可能会让事情变得更可能:)很高兴我能帮上忙!我可以发誓我已经测试过了,但你完全正确。我刚刚测试了它,至少在Express4.x中,next没有返回任何东西(我希望得到一个承诺),所以目前我的做法根本不可行。我将切换到您提到的两个中间件解决方案作为我的后备方案。谢谢。@dpwrussell一点也不担心,我不知道express 5会带来什么,它可能会让事情变得更可能:)很高兴我能帮上忙!