• flask信号


      骚师博客:信号

      信号你就可以这么理解,请求比喻成赛车,请求走的流程就是赛车道,而信号坐落在赛车道上的加油站和维修站,信号注册的函数好比维修站的人,每经过维修站并且维修站里有人就进行维修

      信号这里理解:信号决定了在哪个时候执行,注册的函数定义了该怎么做,请求来时触发信号里的函数

        对于信号,你看完后你会觉得,感觉和之前的请求扩展没啥区别样的,但是了解好它的执行先后顺序,对以后进行开放封闭式开发是有益处的,所以我们需要稍稍了解一下其中的源码

      触发信号: signals.request_started.send() , 找这个就好了

    from flask import Flask,signals,render_template
    
    app = Flask(__name__)
    
    # 往信号中注册函数
    def func(*args,**kwargs):
        print('触发型号',args,kwargs)
    signals.request_started.connect(func)
    
    # 触发信号: signals.request_started.send()
    
    @app.before_first_request
    def before_first1(*args,**kwargs):
        pass
    @app.before_first_request
    def before_first2(*args,**kwargs):
        pass
    
    @app.before_request
    def before_first3(*args,**kwargs):
        pass
    
    
    
    @app.route('/',methods=['GET',"POST"])
    def index():
        print('视图')
        return render_template('index.html')
    
    
    if __name__ == '__main__':
        app.wsgi_app
        app.run()
    

      我们还看到flask最核心的这段代码 

            ctx = self.request_context(environ)
            ctx.push()
            error = None
            try:
                try:
                    response = self.full_dispatch_request()
                except Exception as e:
                    error = e
                    response = self.handle_exception(e)
                except:
                    error = sys.exc_info()[1]
                    raise
                return response(environ, start_response)
            finally:
                if self.should_ignore_error(error):
                    error = None
                ctx.auto_pop(error)

       其中前面几句里的执行没发现send,直接看到full_dispatch_request

            #执行before_first_request
            self.try_trigger_before_first_request_functions()  #使用标志位实现,请求过程@app.before_first_request把函数添加到列表中
            try:
                #触发request_started信号
                request_started.send(self)
                #调用before_request
                rv = self.preprocess_request()
                if rv is None:  #没有返回值继续执行
                    '''
                    #执行before_render_template 渲染前信号
                    before_render_template.send(app, template=template, context=context)
                    rv = template.render(context)  #模板渲染
                    #执行template_rendered 渲染后信号
                    template_rendered.send(app, template=template, context=context)
                    '''
                    #执行视图函数
                    rv = self.dispatch_request()
            except Exception as e:
                rv = self.handle_user_exception(e)
            #对返回值做进一步处理
            return self.finalize_request(rv)
    

       并且在finalize_request中

            response = self.make_response(rv)
            try:
                #处理after_request
                #session.save
                response = self.process_response(response)
                #触发request_finished信号
                request_finished.send(self, response=response)
            except Exception:
                if not from_error_handler:
                    raise
                self.logger.exception('Request finalizing failed with an '
                                      'error while handling an error')
            return response
    

       所以在full_dispatch_request里的触发顺序为

    1. 执行before_first_request
    2.    触发request_started信号
    3. 执行before_request
    4.    执行before_render_template 渲染前信号(存在模板渲染才执行)
    5. 模板渲染
    6.    执行template_rendered 渲染后信号
    7. 执行视图函数
    8.    处理after_request
    9. session.save
    10. 触发request_finished信号

      下一句代码中,response = self.handle_exception(e),上述10步骤中,任何一步出错,触发错误处理got_request_exception信号

            exc_type, exc_value, tb = sys.exc_info()
    
            got_request_exception.send(self, exception=e)
            handler = self._find_error_handler(InternalServerError())
    

       

      最后在ctx.auto_pop(error)中,一直往下找,有这么一个方法,方法里会触发request_tearing_down信号,表示无论成功与否,都会执行

      所以最后还会走 执行request_tearing_down信号

      

  • 相关阅读:
    vue-router replace 浏览器前进后退记忆栈不记住当前菜单页面
    vue-router active-class 进入当前菜单的样式
    vue-router createWebHashHistory
    浅析如何升级npm及更新npm之后报错(node:15920) ExperimentalWarning: The fs.promises API is experimental 的解决
    浅析nvm介绍、安装与使用以及遇到的问题解决
    npm安装vue-cli报错internal/modules/cjs/loader.js(Error: Cannot find module 'D:Program odejs ode_global ode_modulesvue-cliinvue')
    浅析如何升级vue-cli以及使用npm卸载包时遇到问题:npm ERR! code EEXIST(npm ERR! File exists: D:Program odejs ode_globalvue-list.cmd
    浅析如何实现根据图片自动切换背景色功能:提取图片主题色方案探索
    sync.Pool is much slower than using channel, so why should we use sync.Pool?
    golange benchmark运行
  • 原文地址:https://www.cnblogs.com/xinsiwei18/p/9595690.html
Copyright © 2020-2023  润新知