• 【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--请求处理结果适配篇(7/8)


    文章目录

    前情概要

    前面一大坨一大坨的代码把route、controller、action、attribute都搞完事儿了,最后剩下一部分功能就是串起来的调用。
    那接下就说个说第二个中间件,也是最后一个中间件RequestHandler

    RequestHandler 中间件的注册

    app.use一下就完事啦。在RouteHandler把路由处理好之后,接着就是RequestHandler真正的来调用我们的处理函数啦,也就是我们的action。

    import { RequestHandler, RouteHandler } from 'gd-express-basic'
    //第二个中间件,拦截所有请求对路由做自动映射
    RouteHandler(_app, controllers);
    //第三个中间件,处理请求
    _app.use(RequestHandler);
    

    RequestHandler 请求处理中间件代码

    1. 从当前请求拿到对应的action描述对象,如果没有就继续往后面的中间件走,比如走到404。
    2. new一个新的controller对象,并把req,res对象传入。
    3. 完成参数的自动解析
    4. 调用action,得到返回结果
    5. 判断返回结果是否view类型,如果是view类型则调用render来渲染页面,如果不是则返回该对象
    6. 判断需要返回的对象是否是jsoncallback调用方式,是的话就适配一下
      7.完事儿
    /**
     * 请求处理中间件
     * 
     * @export
     * @param {core.Request} req 
     * @param {core.Response} res 
     * @param {(core.NextFunction | undefined)} next 
     */
    export function RequestHandler(req: core.Request, res: core.Response, next: core.NextFunction | undefined) {
    //1. 从当前请求拿到对应的action描述对象,如果没有就继续往后面的中间件走,比如走到404。
        var desc: ActionDescriptor = res.locals.actionDescriptor
        if (!desc) {
            return next && next();
        }
        var cname = desc.ControllerName;
        new Promise((reslove, reject) => {
            var cType = desc.ControllerType;//*controller class对象
            //2. new一个新的controller对象,并把req,res对象传入。
            var c = new cType(req, res);//new 一个controller 对象出来
            //3. 完成参数的自动解析
            var agrs = bindActionParameter(desc.ControllerType, desc.ControllerTypeName, desc.ActionType, desc.ActionName, req)
            //4. 调用action,得到返回结果
            var actionResult = desc.ActionType.apply(c, agrs)
            return reslove(actionResult)
        }).then(actionResult => {
            if (actionResult instanceof ViewResult) {
            //5. 判断返回结果是否view类型,如果是view类型则调用render来渲染页面,如果不是则返回该对象
                Promise.resolve(actionResult.data).then(ViewActionResultData => {
                    var findViewNamePath = actionResult.name[0] === '/' ? actionResult.name.substr(1) : (cname + '/' + actionResult.name)
                    res.render(findViewNamePath, ViewActionResultData, (err, html) => {
                        if (err) {
                            next && next(err);
                        } else {
                            res.send(html);
                            res.end();
                        }
                    });
                }).catch(function (viewDataError) {
                    next && next(viewDataError);
                });
            } else if (typeof actionResult !== 'undefined') {
                //process object send response json
                //6. 判断需要返回的对象是否是jsoncallback调用方式,是的话就适配一下
                let resultData = req.query['callback'] ? req.query['callback'] + '(' + JSON.stringify(actionResult) + ')' : actionResult;
                res.send(resultData);
                res.end()
            } else {
                //process not response or origin response.render or response.send.
                process.nextTick((_res: any) => {
                    if (!_res.finished) {
                        _res.end();
                    }
                }, res)
            }
        }).catch(processRequestError => {
            next && next(processRequestError);
        })
    }
    

    经过RouteHandler、RequestHandler两个方法的串联调用,就把我们整个零散的功能就完整统一的进行了一次调用。从controller的发现、注册,action的发现、注册,action参数配置,route解析、匹配,action调用,处理结果适配输出。

    在编码调试过程中,发现目前dotnet core mvc的中间件的某些思想和实现方式和express的中间件基本一致。果然,思想都是相同的,哈哈哈。

  • 相关阅读:
    LAMP的搭建
    linux利用命令重置大量密码
    CSS的应用下
    Day13 CSS的与应用
    Day12 CSS简单用法
    Day12 前端html
    Day11 数据库的基本语法(偏重于查询)
    Java-->把txt中的所有字符按照码表值排序
    Java-->将txt文件的所有行反转
    Java-->在txt文件每一行前加行数和冒号
  • 原文地址:https://www.cnblogs.com/calvinK/p/nodejs-mvc-process-result-format.html
Copyright © 2020-2023  润新知