最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • kraken: js执行时机

    正文概述 掘金(林鹿)   2021-04-28   449
    flutter: 2.0.1
    kraken: main@b5574e6
    

    查看源码一定要带着问题,有针对性的了解不然会陷入代码的汪洋大海中,对于整个仓库有个通观概览的认识,先看效果。运行仓库中的示例代码(kraken/example/assets/bundle.js)可以看到生成了flutter节点控件: kraken: js执行时机 源码片断如下:

    var text1 = document.createTextNode('Hello World!');
    var br = document.createElement('br');
    var text2 = document.createTextNode('你好,世界!');
    p.style.textAlign = 'center';
    ...
    p.appendChild(text1);
    

    于是很自然的,我们想知道js生成节点如何与dart控件对应的;要运行js文本那js引擎必须准备好,它是如何初始化的;同时外部传入的assets/bundle.js是什么时机读取并传给引擎执行的:

    1. js生成节点如何与dart控件对应

    2. js引擎初始化的时机

    3. 运行指定js文件的时机

    概览

    从示例应用(kraken/example/lib/main.dart)的来看,入口还是相对清晰的,直接将Kraken对象作为Scaffold的body主体,接收了参数assets/bundle.js作为bundlePath的值,跟踪它就解决问题3。

    Kraken是一个无状态的Widget, 创建的子控件为_KrakenRenderObjectWidget, 它又是一个SingleChildRenderObjectWidget,这种控件是为了专门绘制单个节点的控件,最重要的2个方法:RenderObject createRenderObject(BuildContext context)创建一个绘制对象;_KrakenRenderObjectElement createElement()创建控件对应的节点(Element)。

    先明析一个概念,前端经常说到渲染,但这里的渲染不是指具体的绘制操作,一般是输出一段html文本或者几个vnode节点交由浏览器作解析,离绘制还有很长一段距离。flutter里的RenderObject(渲染对象)是真正的绘制,在这里需要有尺寸,内容,色值,画刷等相关的对象去进行绘制操作(离屏幕上出现绘制内容其实也有不小的距离),所以为了防止一些名词上的混乱,一概以绘制代替渲染。

    另一个概念是节点Element,flutter里的Element不区分TextNode也没有显式的appendChild操作,也不是html/xml文本里说的元素,它由Widget创建(Element createElement()是Widget的抽象方法)并且与Widget一一对应。

    再一个需要回顾的是flutter框架如何建立控件节点树相关的一些机制。简而言之,我们是先得有Widget对象,它来创建一个节点(Element),节点具体做父子关系建立的工作,这样节点树通过各种类型的Widget及其build方法建立起来,这一步由flutter框架完成的,外部不能自己持有节点自行建立层级关系,这一过程叫做挂载(mount)。

    所以就可以明白_KrakenRenderObjectElement的唯一方法void mount(Element parent, dynamic newSlot) async {的作用了。

    Widget Kraken.build(BuildContext)void _KrakenRenderObjectElement.mount(Element parent, dynamic newSlot)是异步的,中间显然创建了非常多的东西,一步一步来看。

    于是按上面的概览总体的分了4步:

    1 Kraken.build()
      _KrakenRenderObjectWidget()
    
    2 _KrakenRenderObjectWidget.createRenderObject
    
    3 _KrakenRenderObjectWidget.createElement
    
    4 _KrakenRenderObjectElement.mount
    
    

    步骤1几乎没什么操作,只是生成对象持有外部传入数据

    步骤4的代码也不多,其实已经知道问题3的答案了,不确定的话查找一下传入的_bundlePath的最终引用,其实就是在KrakenController.loadBundle这个方法里。深入代码再看一下方法调用:

    4 _KrakenRenderObjectElement.mount
      4.1 KrakenController.loadBundle
        KrakenBundle.getBundle
          AssetsBundle()
          *AssetsBundle.resolve
      4.2 _evalBundle
        controller.evalBundle()
          KrakenBundle.eval
            evaluateScripts
              _evaluateScripts
                'evaluateScripts'
    

    就2步 4.1载入资源js文本,具体解析资源的是AssetsBundle, 基类是KrakenBundle

    4.2调用js引擎求值(evaluate),这里用了个全局方法_evalBundle,真是匪夷所思的操作,所有对象都在KrakenController里还搞个全局方法; 最终通过dart的ffi调用了js引擎库的方法 'evaluateScripts'

    于是问题3答案近在咫尺: Kraken是在挂载节点的时候读取内容,再由js引擎执行

    问题接踵而至js引擎又是何时完成初始化的?


    起源地下载网 » kraken: js执行时机

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元