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信号

 

 

  

posted @ 2018-09-07 10:46  财经知识狂魔  阅读(161)  评论(0编辑  收藏  举报