`
yiminghe
  • 浏览: 1431531 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

模块的静态与动态循环依赖

 
阅读更多

场景:

 

循环依赖 我是不支持的,但现实中似乎又确实需要循环依赖,例如前端的选择器场景 (ie<8):

 

首先实现了 DOM 模块来保证各个浏览器的兼容性以及 api 的易用性,其中包含必要简单的选择器逻辑

 

然后实现了高级选择器模块,但这并不是最常用,为了效率该模块是不放入核心 DOM 模块中的,而选择将它作为独立模块 :selector,显然 selector 模块依赖于 DOM 进行 dom 遍历.

 

S.add("selector",function(){

},{requires:["dom"]});

 

而 DOM 中会进行判断是否当前选择器字符串过于负责而自己不能处理,需要高级选择器模块介入:

 

S.add("dom",function(S,Selector){
  return {
      querySelectorAll:function(q){
           if(isAdvanced(q)){
               return Selector.querySelectorAll(q);
           } else{
               // simple logic
           }
      }
  };
},{requires:["selector"]});

 

这时就形成了循环依赖

 

解决:

 

其实我们需要区分模块间到底是静态依赖还是动态依赖,静态依赖指模块的初始化就需要另一个模块参与,而动态依赖则是指直到模块的运行期才会需要调用另一个模块,对于静态循环依赖这个问题我觉得是无解的,而对于动态循环依赖则是完全可以绕过.

 

动态循环依赖可以参考类似 serviceloader 的做法,DOM 模块完全可以动态取得高级选择器接口的一个具体实现模块,而selector 模块实现接口并保证自己可以被找到即可:

 

DOM 模块:

 

S.add("dom",function(S){
  return {
      querySelectorAll:function(q){
           if(isAdvanced(q)){
               return S.ServiceLoader.load("selector").querySelectorAll(q);
           } else{
               // simple logic
           }
      }
  };
});

 

高级选择器模块仍可以依赖 DOM ,实现 querySelectorAll 接口(概念上,动态语言完全没必要),并注册自己即可.

 

而 ServiceLoad.load 完全可以和模块系统结合在一起,用户可以通过模块系统静态或动态载入一些高级附加模块,ServiceLoad.load 询问模块系统即可得到实现了高级选择器接口的具体模块.

 

 

 

refer:

 

static vs dynamic 1 ,2

 

circular dependency wiki

 

java.util.ServiceLoader api

 

 

 

分享到:
评论
2 楼 yiminghe 2011-07-25  
limu 写道
我也遇到这个问题,在seajs里遇到类似的问题.
把动态依赖的require改为require.async.
因为初始时一定是require过这俩,require.async的目标模块在调用时肯定已经被载入
所以调用时就是同步的,可以按同步的写法继续写余下的代码,而不用封装到回调中.

哈,kissy 一直是通过 S.require("sizzle") 来解决的,不过看到后端语言的对应支持很踏实
1 楼 limu 2011-07-25  
我也遇到这个问题,在seajs里遇到类似的问题.
把动态依赖的require改为require.async.
因为初始时一定是require过这俩,require.async的目标模块在调用时肯定已经被载入
所以调用时就是同步的,可以按同步的写法继续写余下的代码,而不用封装到回调中.

相关推荐

    dpdm:检测 TypeScript 项目中的循环依赖

    用于JavaScript和TypeScript项目的静态依赖项分析器。 特征 支持CommonJS 、 ESM 。 完全支持JavaScript和TypeScript 。 支持 TypeScript 。 支持忽略 TypeScript 类型依赖 轻量级:使用解析所有模块。 快速:...

    akg-master.zip

    规范化模块中的优化主要包括自动运算符inline、自动循环融合和公共子表达式优化等。自动调度: 自动调度模块基于polyhedral技术,主要包括自动向量化、自动切分、thread/block映射、依赖分析和数据搬移等。后端优化...

    综合电子设备管理系统的可维护性设计.doc

    首先,各个子系统的内部模块必须是单向依赖,对出现循环依赖的模块,我们采用调整 功能分布,抽取公共模块等方面消除循环依赖。其次,对于接口子系统,我们需要对某 些模块内部进行深入的测试,而由于模块接口的...

    综合电子设备管理系统的可维护性设计(1).doc

    首先,各个子系统的内部模块必须是单向依赖,对出现循环依赖的模块,我们采用调整 功能分布,抽取公共模块等方面消除循环依赖。其次,对于接口子系统,我们需要对某 些模块内部进行深入的测试,而由于模块接口的...

    C++/C编程规范

     如何(和为什么要)避免不必要的初始化、循环依赖和定义依赖?  何时应该(以及如何)同时使用静态和动态的多态性;  如何实践“安全的”改写?  何时该提供不会失败的交换?  为什么阻止异常跨越模块边界传播...

    高质量 C++/C 编程指南

    ,  如何(和为什么要)避免不必要的初始化、循环依赖和定义依赖?,  何时应该(以及如何)同时使用静态和动态的多态性?,  如何实践“安全的”改写?,  何时该提供不会失败的交换?,  为什么要阻止异常...

    C++编程规范

    ,  如何(和为什么要)避免不必要的初始化、循环依赖和定义依赖?,  何时应该(以及如何)同时使用静态和动态的多态性?,  如何实践“安全的”改写?,  何时该提供不会失败的交换?,  为什么要阻止异常...

    jQuery 数据缓存模块进化史详细介绍

    数据缓存系统最早应该是jQuery1.2引入的,那时它的事件系统完成照搬DE大神的addEvent.js,而addEvent在实现有个缺憾,它把事件的... jQuery1.2 在core模块新增了两个静态方法, data与removeData。data不用说,与jQuery

    syntactic:syntactic.js 提供了一个 API 用于学生 javascript 代码的静态分析

    syntactic.js 提供了一个 API,用于对用于教育环境的 javascript 代码进行静态分析。 该 API 允许您: 白名单和黑名单的语法特征(如 for 循环、while 循环等) 测试两个代码示例共享相同的通用结构。 你可以在...

    精通AngularJS part1

    模块与依赖注入26 模块26 协作对象27 注册服务29 模块的生命周期33 模块依赖35 13AngularJS和其他框架38 jQuery与AngularJS39 苹果与橙子40 窥视未来41 14总结41 第2章构建与测试43 21介绍示例应用44 ...

    软件工程-理论与实践(许家珆)习题答案

    RCP法与RSP法的主要区别是前者采用循环渐进的开发方式,原型将成为最终的产品,而后者将被废弃。(√) 三、简答题 1. 软件产品的特性是什么? 答: ● 软件是一种逻辑产品,具有无形性;  ● 软件产品的生产...

    JavaScript模式中文[pdf] 百度云

     传统与现代继承模式的比较  使用类式继承时的预期结果  类式继承模式#1——默认模式  类式继承模式#2——借用构造函数  类式继承模式#3——借用和设置原型  类式继承模式#4——共享原型  类式继承模式#5——...

    JavaScript模式 斯托扬·斯特凡洛夫 著

    传统与现代继承模式的比较 使用类式继承时的预期结果 类式继承模式#1——默认模式 类式继承模式#2——借用构造函数 类式继承模式#3——借用和设置原型 类式继承模式#4——共享原型 类式继承模式#5——临时构造函数 ...

    美国..现代编译原理C语言描述.高清版

    10.1.5 静态活跃性与动态活跃性 160 10.1.6 冲突图 161 10.2 Tiger编译器的活跃分析 162 10.2.1 图 162 10.2.2 控制流图 163 10.2.3 活跃分析 164 程序设计:构造流图 164 程序设计:活跃分析模块 165 习题 165 第...

    learn-fe:路漫漫其修远兮, 吾将上下而求索

    模块化循环依赖 underscore 源码解析 canvas 实现多行文本自动换行 CSRF 漏洞示例 XSS 漏洞示例 归并排序 快速排序 选择排序 冒泡排序 各种排序算法 隐藏滚动条 数组去重 2020-01 Proxy 工具, 用于处理跨域请求 ...

    akg:AKG(自动内核生成器)是针对深度学习网络中的运营商的优化器,提供了将操作与特定模式自动融合的功能

    标准化模块的主要优化包括自动内联,循环融合,公共子表达式消除等。 自动排程。 自动调度模块基于多面技术,主要具有自动矢量化,自动平铺,线程/块映射,依赖关系分析和内存提升。 后端优化。 后端优化模块主要...

    计算机二级公共基础知识

    例如,在一维数组[21,46,24,99,57,77,86]中,查找数据元素99,首先从第1个元素21开始进行比较,比较结果与要查找的数据不相等,接着与第2个元素46进行比较,以此类推,当进行到与第4个元素比较时,它们相等,...

    ArchTest 是一个基于规则的 Rust 架构测试工具

    特征检测循环依赖级别或模块明智禁止家长访问定义层关系,如MayNotAccess 、MayOnlyAccess 、MyNotBeAccessedBy 、MayOnlyBeAccessedBy更多内容请查阅文档。安装您可以将其作为 Cargo 的子命令安装,也可以作为开发...

    Gallery-R:进行中 - JS Interactive Gallery Exhibit 用于展示采访视频

    画廊 R NMDE 305:运动图形最终项目 IGME 330:Rich Media Web App Dev I 最终项目 概括 这是互动展览的一部分,该... - Browserify 用于模块加载和依赖管理 - Sass (scss) 用于样式 - Firebase 用于后端(数据库)

    Python第一阶段笔记汇总.docx

    (三)依赖倒置(依赖抽象) 96 (四)组合复用原则(复用的最佳实践) 96 (五)里氏替换(扩展重写,继承后的重写,指导继承的设计) 96 (六)迪米特法则(用父类减少传递数据量,类与类交互的原则) 97 第三章 模块包+...

Global site tag (gtag.js) - Google Analytics