zoukankan      html  css  js  c++  java
  • seajs模块加载与执行原理小记

    本文仅讨论具名模块的情况,即通过spm打包出来的模块.

    想起ID与路径统一原则,详见https://github.com/seajs/seajs/issues/930

    今天又研究了下seajs源码,源码中并没有显式的判断id与路径相不相等,即没有类似如下的代码

    if(id == uri){

      mod.exec();

    }

    假定被加载的模块为a.js

    step1:在加载a.js前,就创建并缓存了a.js的module实例A,key值为a.js的全路径,暂定为uriA

    step2:定义好onload事件(这里ie又出来捣乱了),创建script标签插入head

    step3:浏览器加载完a.js后,执行define方法跟踪代码到seajs内部,发现并没有做什么特别的事,只是调用了Module.save方法,id与路径的匹配即体现在这个save方法中.且看源码:

     1 // Save meta data to cachedMods
     2 Module.save = function(uri, meta) {
     3   var mod = Module.get(uri)
     4 
     5   // Do NOT override already saved modules
     6   if (mod.status < STATUS.SAVED) {
     7     mod.id = meta.id || uri
     8     mod.dependencies = meta.deps || []
     9     mod.factory = meta.factory
    10     mod.status = STATUS.SAVED
    11   }
    12 }

    第3行,获取缓存中的module,uri是模块中的id.

    假如id与加载路径相等,那么这里可以获取到step1缓存的A,然后将factory等属性赋给A,结束

    假如id与加载路径不相等,那么这里将获取不到A,会新创建一个新实例B

    step4:浏览器执行完a.js的代码,执行onload回调,进行一系列的属性操作(比如waiting和remain)和依赖模块的加载等等,这里有递归...需要花点时间才能看懂.

    step5:等step4的所有递归执行完,也即a.js及其所有依赖模块都已加载完,执行完,进入就绪状态,执行a.js的factory,这里的factory从A中获取,A通过uriA从缓存中获取.

             如果step3中,a.js中的id与加载它的路径不一致,那么这里A中的factory将是undefined,所以你的factory方法就不执行.

    以上是seajs处理模块的大致流程.

    至于使id与路径一致,通常的做法是,use或require里的直接量字符串参数与模块里的id相等.比如

    //html页面
    seajs.use("app/start",function(){ // code }) //start.js define("app/start",["jquery/jquery/1.7.2/jquery"],function(require, exports, module){ //code })

    不过,这两个值通过seajs内部resolve过后能相等,也是可以的.

  • 相关阅读:
    leetcode第四题
    解决Hystrix主线程结束,子线程拿不到request
    RabbitMQ如何保证消息的顺序性+解决消息积压+设计消息队列中间件
    RabbitMQ 如何保证消息不丢失?
    redis布隆过滤器的使用
    PageHelper自定义count
    mysqlbinlog 工具分析binlog日志
    linuxubuntu常用命令
    MySQL 常用命令
    Ubuntu 16.04 安装 Apache, MySQL, PHP7
  • 原文地址:https://www.cnblogs.com/webstone/p/3681680.html
Copyright © 2011-2022 走看看