seaJS循环依赖的解决原理

seajs模块的六个状态。

var STATUS = { 
  ‘FETCHING‘: 1, // The module file is fetching now. 模块正在下载中 
  ‘FETCHED‘: 2, // The module file has been fetched. 模块已下载 
  ‘SAVED‘: 3, // The module info has been saved. 模块信息已保存 
  ‘READY‘: 4, // All dependencies and self are ready to compile. 模块的依赖项都已下载,等待编译 
  ‘COMPILING‘: 5, // The module is in compiling now. 模块正在编译中 
  ‘COMPILED‘: 6 // The module is compiled and module.exports is available. 模块已编译 
}

我们假设a.js的代码:

define(function(require, exports, module){
    var b = require(‘./b.js‘);
    //......
});

b.js的代码:

define(function(require, exports, module){
    var a = require(‘./a.js‘);
    //......
});

循环依赖的概念:seajs在使用a模块时,会先下载a模块,a模块下载时,a模块的状态是FETCHING,下载好了之后,a模块的状态是FETCHED,然后解析a模块,这时会从a模块的回调函数中寻找a模块依赖的模块,这里a模块依赖的模块是b模块。这时,a模块的状态变成了SAVED,然后去下载b模块,这时b模块的状态是FETCHING,下载好了之后,b模块的状态是FETCHED,然后解析b模块,这时会从b模块的回调函数中寻找b模块依赖的模块,这里b模块依赖的模块是a模块。这里就产生了循环依赖的问题。

seajs里面是如何解决这个问题的呢?

此问题,非常重要,不信,你等着看。

seajs中处理这个问题的第一步:

在a模块的回调函数中寻找a模块依赖的模块后(这时a模块的状态是SAVED了),会判断a模块所依赖的模块是否跟自己有循环依赖的关系,如果有,就不去下载,seajs是通过getPureDependencies方法进行判断的,由于这时b模块还不存在于cachedModules中,所以这里不会检查出a与b有循环依赖的关系。

因此,去下载b模块,下载好了之后,b模块的状态是FETCHED,然后解析b模块,这时就会从b模块的回调函数中寻找b模块依赖的模块,这里检查出来了是a模块,这时b模块的状态变成了SAVED的。然后判断a模块是否与自己(b模块)循环依赖。由于此时a模块存在,并且状态是SAVED,这时就会检查出来了有依赖,因此b模块的状态就会直接变成了READY。

这时,a模块的状态就会变成READY(如果a模块还依赖其他的模块,比如c模块,那么等c模块变成READY后,a模块才会变成READY状态)。这时,就会去编译a模块,a模块的状态是COMPILING,编译过程,其实就是执行a模块的回调函数,(如果这里a模块依赖的是c模块,这时,就会执行c模块的回调函数,也就是编译c模块,编译结束后,c模块变成了COMPILED),紧接着,a模块变成COMPILED。

但是,这里依赖的是b模块,因此,在执行a模块的回调函数时(在编译a模块时),会执行b模块的回调函数,也就是编译b模块,等编译结束,b模块变成了COMPILED,紧接着a模块就变成了COMPILED。

循环依赖的分析到此结束,大家可以跟着我的另一篇博客一起分析。

http://www.cnblogs.com/chaojidan/p/4126647.html

加油!

时间: 2024-12-11 09:55:08

seaJS循环依赖的解决原理的相关文章

Spring中-IOC-Bean的初始化-循环依赖的解决

前言 在实际工作中,经常由于设计不佳或者各种因素,导致类之间相互依赖.这些类可能单独使用时不会出问题,但是在使用Spring进行管理的时候可能就会抛出BeanCurrentlyInCreationException等异常 .当抛出这种异常时表示Spring解决不了该循环依赖,本文将简要说明Spring对于循环依赖的解决方法. 循环依赖的产生和解决的前提 循环依赖的产生可能有很多种情况,例如: A的构造方法中依赖了B的实例对象,同时B的构造方法中依赖了A的实例对象 A的构造方法中依赖了B的实例对象

CocoaPods 0.35.0版本, 出现循环依赖的解决办法

Cocoapods目前最新的正式版本是0.35.0,如果升级到这个版本,并且在project中使用XMPPFramework,在pod install之后会出现如下循环依赖的问题 There is a circular dependency between XMPPFramework/Core and XMPPFramework/Authentication 解决方案,是要么放弃使用XMPPFramework, 要么降级CocoaPods版本到 0.34.4. 这里采用后者 1, 卸载 coco

spring源码编译orm模块报循环依赖错误解决方法

根据别的大神的路线,一步步配置spring源码的时候,编译orm报如下错误: BUILD FAILED in 3s   Circular dependency between the following tasks:   :spring-beans:compileGroovy   \--- :spring-beans:compileJava   \--- :spring-beans:compileKotlin   \--- :spring-beans:compileGroovy (*)    

Spring循环依赖原因及如何解决

浅谈Spring解决循环依赖的三种方式 SpringBoot构造器注入循环依赖及解决 原文:https://www.baeldung.com/circular-dependencies-in-spring 代码:https://github.com/eugenp/tutorials/tree/master/spring-di 原文地址:https://www.cnblogs.com/liran123/p/11655604.html

Spring 如何解决循环依赖的问题

Spring 如何解决循环依赖的问题 https://blog.csdn.net/qq_36381855/article/details/79752689 Spring IOC 容器源码分析 - 循环依赖的解决办法 https://www.imooc.com/article/34150 原文地址:https://www.cnblogs.com/tonggc1668/p/11751384.html

spring怎么解决循环依赖

spring怎么解决循环依赖?首先会根据 beanName 从单例 bean 缓存中获取,如果不为空则直接返回 主要是从三个缓存中获取 (称他们为3级缓存),分别是: singletonObjects (1 单例对象的cache) earlySingletonObjects(2 提前暴光的单例对象的Cache ) singletonFactories (3 单例对象工厂的cache )getSingleton() 整个过程如下: 首先从一级缓存 singletonObjects 获取,如果没有且

Spring循环依赖

Spring-bean的循环依赖以及解决方式 Spring里面Bean的生命周期和循环依赖问题 什么是循环依赖? 循环依赖其实就是循环引用,也就是两个或者两个以上的bean互相持有对方,最终形成闭环.比如A依赖于B,B依赖于C,C又依赖于A.如下图: 注意,这里不是函数的循环调用,是对象的相互依赖关系.循环调用其实就是一个死循环,除非有终结条件. Spring中循环依赖场景有: (1)构造器的循环依赖 (2)field属性的循环依赖 其中,构造器的循环依赖问题无法解决,只能拋出BeanCurre

Spring之循环依赖

转:http://my.oschina.net/tryUcatchUfinallyU/blog/287936 概述 如何检测循环依赖 循环依赖如何解决 Spring如何解决循环依赖 主要的几个缓存 主要步骤 Spring不能完全解决的循环依赖问题 面对Spring不能完全解决的现状,我们该如何处理 概述 入职的时候学习spring研究过循环依赖,现在再回顾下,发现啥都忘记了,还是得总结下来,故总结该文. 本文主要解决如下问题: 1.何为循环依赖 2.如何检测循环依赖 3.循环依赖可以如何解决 4

SPRING循环依赖(circular reference)的解决方法

循环依赖,就是说类A依赖与B,而B又依赖于A,这种情况本不应该发生,发生这种情况是因为我在项目中使用的工厂模式,用一个工厂来生产一些管理器类,而某一管理器要需要另一管理器提供支持所以就要引用工厂类,而这个管理器和这个工厂就出现了循环依赖(项目中实际的逻辑比这个更复杂,因为我在项目中实现的了一个工作流数据POJO类延迟加载的功能像hibernate 那样在调用一个类的集合属性时才到要shark中去查找数据而不是在new里加载,并且这个数据类的集合属性并不包含加载数据的代码只是普通的Bean方法ge