为什么springcloud 服务治理 cloud服务注册不上去

Spring Cloud Eureka 入门 (一)服务注册中心详解 2. Maven 编译安装这个工程:cd springcloud-learning-example
mvn clean install
3. 运行 springcloud-eureka-server Eureka 工程右键 Main 函数 Run Eureka Server 启动类 EurekaServerApplication,启动服务注册中心工程。EurekaServerApplication 类地址:/springcloud-learning-example/springcloud-eureka-sample/springcloud-eureka-server/src/main/java/org/spring/springboot/EurekaServerApplication.java控制台 Console 看到这类信息,代表启动成功: 10:32:47.549
INFO 2977 --- [
Thread-11] e.s.EurekaServerInitializerConfiguration : Started Eureka Server
10:32:47.625
INFO 2977 --- [
main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8888 (http)
10:32:47.626
INFO 2977 --- [
main] .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to 8888
10:32:47.632
INFO 2977 --- [
main] o.s.springboot.EurekaServerApplication
: Started EurekaServerApplication in 23.168 seconds
4. 访问 Eureka 注册中心可视化界面打开浏览器,访问
,如图所示 可以看到主体信息包括:– 系统状态:环境、运行时间、更新时间等– 注册信息:服务名、服务地址、服务状态– 基本信息:环境、内存、副本信息– 实例信息:IP、端口三、详解 Eureka 工程 springcloud-eureka-server 1.springcloud-eureka-server
工程目录结构├── pom.xml
└── src
└── main
├── java
└── org
└── spring
└── springcloud
├── EurekaServerApplication.java
└── resources
└── application.yml
EurekaServerApplication.java Eureka Server 启动类application.yml 配置文件2. pom.xml 配置 &?xml version="1.0" encoding="UTF-8"?&
&project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/ma ... gt%3B
&modelVersion&4.0.0&/modelVersion&
&groupId&springcloud&/groupId&
&artifactId&springcloud-eureka-server&/artifactId&
&version&0.0.1-SNAPSHOT&/version&
&name&springcloud-eureka-server :: Spring Cloud Eureka 服务注册中心&/name&
&!-- Spring Boot 启动父依赖 --&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-starter-parent&/artifactId&
&version&1.5.4.RELEASE&/version&
&dependencies&
&!-- Spring Cloud Netflix Eureka Server 依赖 --&
&dependency&
&groupId&org.springframework.cloud&/groupId&
&artifactId&spring-cloud-starter-eureka-server&/artifactId&
&/dependency&
&!-- Spring Boot Test 依赖 --&
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-starter-test&/artifactId&
&scope&test&/scope&
&/dependency&
&/dependencies&
&dependencyManagement&
&dependencies&
&!-- Spring Cloud Netflix 依赖 --&
&dependency&
&groupId&org.springframework.cloud&/groupId&
&artifactId&spring-cloud-netflix&/artifactId&
&version&1.3.1.RELEASE&/version&
&type&pom&/type&
&scope&import&/scope&
&/dependency&
&/dependencies&
&/dependencyManagement&
&groupId&org.apache.maven.plugins&/groupId&
&artifactId&maven-compiler-plugin&/artifactId&
&configuration&
&source&1.8&/source&
&target&1.8&/target&
&/configuration&
&/plugins&
&/project&
使用的依赖是– spring-cloud-netflix 1.3.1 是 Spring Cloud Dalston.SR1 版本。– spring-cloud-starter-eureka-server Eureka Server 模块依赖上面提到的客户端负载均衡 Ribbon ,可以依赖树中看出 spring-cloud-starter-eureka-server 依赖了 Ribbon 相关的库。因为一般 eureka 本身作为服务自注册实现高可用,也可以作为客户端调用其他服务。3. application.yml 配置server:
port: 8888 # 服务端口
hostname: localhost # 设置主机名
registerWithEureka: false # 是否向 Eureka 注册服务。该应用为服务注册中心,不需要自注册,设置为 false
fetchRegistry: false
# 是否检索服务。该应用为服务注册中心,职责为注册和发现服务,无需检索服务,设置为 false
waitTimeInMsWhenSyncEmpty: 0 # 设置同步为空时的等待时间。默认 5 * MINUTES
application.property,可以看下面的配置解释:– server.port 设置工程服务端口– eureka.instance.hostname Eureka 实例主机名– eureka.client.registerWithEureka 是否向 Eureka 注册服务。服务注册中心服务,没有作为集群,所以不需要自注册,设置为 false– eureka.client.fetchRegistry 是否检索服务。该应用为服务注册中心,职责为注册和发现服务,无需检索服务,设置为 false– eureka.server.waitTimeInMsWhenSyncEmpty 设置同步为空时的等待时间。默认 5 * MINUTES4.注册中心应用启动类/**
* Spring Boot Eureka Server 应用启动类
* Created by bysocket on 21/06/17.
@EnableEurekaServer
// Eureka Server 标识
@SpringBootApplication
// Spring Boot 应用标识
public class EurekaServerApplication {
public static void main(String args) {
// 程序启动入口
// 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件
SpringApplication.run(EurekaServerApplication.class,args);
@EnableEurekaServer 标志该应用作为 Eureka Server ,并会自动化读取相关配置。四、小结此小章节介绍了如何 Eureka 作为服务注册中心 Server,下一小结讲下 服务提供者详解 具体是如何向服务注册中心注册自己的。系列目录如下:Spring Cloud Eureka 入门 (二)服务提供者详解Spring Cloud Eureka 入门 (三)服务消费者详解资料:《Spring Cloud微服务实战》官方文档 10收藏分享举报文章被以下专栏收录高效的中文IT技术平台推荐阅读{&debug&:false,&apiRoot&:&&,&paySDK&:&https:\u002F\\u002Fapi\u002Fjs&,&wechatConfigAPI&:&\u002Fapi\u002Fwechat\u002Fjssdkconfig&,&name&:&production&,&instance&:&column&,&tokens&:{&X-XSRF-TOKEN&:null,&X-UDID&:null,&Authorization&:&oauth c3cef7c66aa9e6a1e3160e20&}}{&database&:{&Post&:{&&:{&isPending&:false,&contributes&:[{&sourceColumn&:{&lastUpdated&:,&description&:&一个专注互联网相关技术的专栏&,&permission&:&COLUMN_PUBLIC&,&memberId&:,&contributePermission&:&COLUMN_PUBLIC&,&translatedCommentPermission&:&all&,&canManage&:true,&intro&:&高效的中文IT技术平台&,&urlToken&:&dreawer&,&id&:21254,&imagePath&:&v2-def9c21d9ca33ad157f4208.jpg&,&slug&:&dreawer&,&applyReason&:&0&,&name&:&极乐科技&,&title&:&极乐科技&,&url&:&https:\u002F\\u002Fdreawer&,&commentPermission&:&COLUMN_ALL_CAN_COMMENT&,&canPost&:true,&created&:,&state&:&COLUMN_NORMAL&,&followers&:24566,&avatar&:{&id&:&v2-def9c21d9ca33ad157f4208&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&activateAuthorRequested&:false,&following&:false,&imageUrl&:&https:\u002F\\u002Fv2-def9c21d9ca33ad157f4208_l.jpg&,&articlesCount&:536},&state&:&accepted&,&targetPost&:{&titleImage&:&&,&lastUpdated&:,&imagePath&:&&,&permission&:&ARTICLE_PUBLIC&,&topics&:[],&summary&:&\u003Cb\u003E本文提纲\u003C\u002Fb\u003E 1. Eureka 服务治理 1.1 什么是 Eureka 1.2 Eureka 集群架构 2. 运行 Eureka 工程 springcloud-eureka-server 3. 详解 Eureka 工程 springcloud-eureka-server \u003Cb\u003E一、Eureka 服务治理\u003C\u002Fb\u003E1.1 什么是 Eureka Eureka,这里是 Spring Cloud Eureka 的简称,…&,&copyPermission&:&ARTICLE_COPYABLE&,&translatedCommentPermission&:&all&,&likes&:0,&origAuthorId&:0,&publishedTime&:&T10:51:51+08:00&,&sourceUrl&:&&,&urlToken&:,&id&:3253670,&withContent&:false,&slug&:,&bigTitleImage&:false,&title&:&Spring Cloud Eureka 入门 (一)服务注册中心详解&,&url&:&\u002Fp\u002F&,&commentPermission&:&ARTICLE_ALL_CAN_COMMENT&,&snapshotUrl&:&&,&created&:,&comments&:0,&columnId&:21254,&content&:&&,&parentId&:0,&state&:&ARTICLE_PUBLISHED&,&imageUrl&:&&,&author&:{&bio&:&生活者&,&isFollowing&:false,&hash&:&784a051feb29da&,&uid&:148400,&isOrg&:false,&slug&:&lee-bysocket&,&isFollowed&:false,&description&:&博客:http:\u002F\&,&name&:&泥瓦匠BYSocket&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Flee-bysocket&,&avatar&:{&id&:&v2-bda1f2f8bb10f13a103b1c32&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&memberId&:,&excerptTitle&:&&,&voteType&:&ARTICLE_VOTE_CLEAR&},&id&:704226}],&title&:&Spring Cloud Eureka 入门 (一)服务注册中心详解&,&author&:&lee-bysocket&,&content&:&\u003Cblockquote\u003E\u003Cp\u003E\u003Cb\u003E本文提纲\u003C\u002Fb\u003E\u003Cbr\u003E1. Eureka 服务治理\u003Cbr\u003E1.1 什么是 Eureka\u003Cbr\u003E1.2 Eureka 集群架构\u003Cbr\u003E2. 运行 Eureka 工程 springcloud-eureka-server\u003Cbr\u003E3. 详解 Eureka 工程 springcloud-eureka-server \u003Cbr\u003E\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Ch2\u003E\u003Cb\u003E一、Eureka 服务治理\u003C\u002Fb\u003E\u003C\u002Fh2\u003E\u003Cp\u003E1.1 什么是 Eureka\u003Cbr\u003EEureka,这里是 Spring Cloud Eureka 的简称,是 Spring Cloud Netflix 组件之一。Spring Cloud Netflix 中核心的组件包括了服务治理(Eureka),服务容断(Hystrix),路由(Zuul)和客户端负载均衡(Ribbon)。在系列第三篇,服务消费者讲解会涉及到 Ribbon 的使用。\u003Cbr\u003E回到 Spring Cloud Eureka,是基于 Netflix Eureka (Netflix 是 Java 实现的开源软件)。服务治理(Eureka)包括服务注册、服务发现和服务检测监控等,自然本文介绍下 Eureka 作为服务注册中心。\u003C\u002Fp\u003E\u003Cp\u003E1.2 Eureka 架构\u003C\u002Fp\u003E\u003Cp\u003EEureka 作为服务治理,必然满足下面几点:\u003Cbr\u003E– 服务本身不存在单点故障,\u003Cbr\u003E– 支持集群,即高可用性\u003Cbr\u003E– 服务与服务之间通过服务注册中心找到彼此实例\u003C\u002Fp\u003E\u003Cp\u003E作为服务端(即服务注册中心),包括\u003Cbr\u003E– 管理服务实例\u003Cbr\u003E– 提供服务注册或下线\u003Cbr\u003E– 提供服务发现\u003Cbr\u003E– 提供服务注册表至两类客户端(即服务提供者和消费者)\u003C\u002Fp\u003E\u003Cp\u003E作为客户端(即服务提供者和消费者),包括\u003Cbr\u003E– 连接服务注册中心\u003Cbr\u003E– 向服务注册中心注册或者下线服务实例\u003Cbr\u003E– 向服务注册中心或服务注册缓存列表查询服务\u003C\u002Fp\u003E\u003Cp\u003EEureka 集群架构如图所示:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Ch2\u003E\u003Cb\u003E二、运行 Eureka 工程 springcloud-eureka-server\u003C\u002Fb\u003E\u003C\u002Fh2\u003E\u003Cp\u003E运行环境:JDK 7 或 8,Maven 3.0+\u003Cbr\u003E技术栈:Spring Cloud Dalston.SR1、 spring-cloud-netflix 1.3.1、Spring Boot 1.5.4\u003C\u002Fp\u003E\u003Cp\u003E1. git clone 下载工程 springcloud-learning-example\u003Cbr\u003E项目地址见 GitHub – \u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002FJeffLiFspringcloud-learning-example\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003Ehttps:\\u002FJeffLiF … ample\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Egit clone https:\\u002FJeffLiF ... e.git\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E 2. Maven 编译安装这个工程:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Ecd springcloud-learning-example\nmvn clean install\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E3. 运行 springcloud-eureka-server Eureka 工程\u003Cbr\u003E右键 Main 函数 Run Eureka Server 启动类 EurekaServerApplication,启动服务注册中心工程。\u003Cbr\u003EEurekaServerApplication 类地址:\u002Fspringcloud-learning-example\u002Fspringcloud-eureka-sample\u002Fspringcloud-eureka-server\u002Fsrc\u002Fmain\u002Fjava\u002Forg\u002Fspring\u002Fspringboot\u002FEurekaServerApplication.java\u003Cbr\u003E控制台 Console 看到这类信息,代表启动成功:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E 10:32:47.549
INFO 2977 --- [
Thread-11] e.s.EurekaServerInitializerConfiguration : Started Eureka Server\n 10:32:47.625
INFO 2977 --- [
main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8888 (http)\n 10:32:47.626
INFO 2977 --- [
main] .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to -06-30 10:32:47.632
INFO 2977 --- [
main] o.s.springboot.EurekaServerApplication
: Started EurekaServerApplication in 23.168 seconds\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E 4. 访问 Eureka 注册中心可视化界面\u003Cbr\u003E打开浏览器,访问 \u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\u002Flocalhost%3AF\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\u003Elocalhost:F\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003E\u003C\u002Fspan\u003E\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E ,如图所示\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E 可以看到主体信息包括:\u003Cbr\u003E– 系统状态:环境、运行时间、更新时间等\u003Cbr\u003E– 注册信息:服务名、服务地址、服务状态\u003Cbr\u003E– 基本信息:环境、内存、副本信息\u003Cbr\u003E– 实例信息:IP、端口\u003C\u002Fp\u003E\u003Ch2\u003E\u003Cb\u003E三、详解 Eureka 工程 springcloud-eureka-server\u003C\u002Fb\u003E \u003C\u002Fh2\u003E\u003Cp\u003E1.springcloud-eureka-server
工程目录结构\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E├── pom.xml\n└── src\n
└── main\n
├── java\n
└── org\n
└── spring\n
└── springcloud\n
├── EurekaServerApplication.java\n
└── resources\n
└── application.yml\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003EEurekaServerApplication.java Eureka Server 启动类\u003Cbr\u003Eapplication.yml 配置文件\u003C\u002Fp\u003E\u003Cp\u003E2. pom.xml 配置 \u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-xml\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&cp\&\u003E&?xml version=\&1.0\& encoding=\&UTF-8\&?&\u003C\u002Fspan\u003E\n\u003Cspan class=\&nt\&\u003E&project\u003C\u002Fspan\u003E \u003Cspan class=\&na\&\u003Exmlns=\u003C\u002Fspan\u003E\u003Cspan class=\&s\&\u003E\&http:\u002F\u002Fmaven.apache.org\u002FPOM\u002F4.0.0\&\u003C\u002Fspan\u003E \u003Cspan class=\&na\&\u003Exmlns:xsi=\u003C\u002Fspan\u003E\u003Cspan class=\&s\&\u003E\&http:\u002F\u002Fwww.w3.org\u002FFXMLSchema-instance\&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&na\&\u003Exsi:schemaLocation=\u003C\u002Fspan\u003E\u003Cspan class=\&s\&\u003E\&http:\u002F\u002Fmaven.apache.org\u002FPOM\u002F4.0.0\u003C\u002Fspan\u003E \u003Cspan class=\&err\&\u003Ehttp:\u002F\u002Fmaven.apache.org\u002Fxsd\u002Fma\u003C\u002Fspan\u003E \u003Cspan class=\&err\&\u003E...\u003C\u002Fspan\u003E \u003Cspan class=\&err\&\u003Egt%3B\u003C\u002Fspan\u003E\n
\u003Cspan class=\&err\&\u003E&modelVersion\u003C\u002Fspan\u003E\u003Cspan class=\&nt\&\u003E&\u003C\u002Fspan\u003E4.0.0\u003Cspan class=\&nt\&\u003E&\u002FmodelVersion&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&groupId&\u003C\u002Fspan\u003Espringcloud\u003Cspan class=\&nt\&\u003E&\u002FgroupId&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&artifactId&\u003C\u002Fspan\u003Espringcloud-eureka-server\u003Cspan class=\&nt\&\u003E&\u002FartifactId&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&version&\u003C\u002Fspan\u003E0.0.1-SNAPSHOT\u003Cspan class=\&nt\&\u003E&\u002Fversion&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&name&\u003C\u002Fspan\u003Espringcloud-eureka-server :: Spring Cloud Eureka 服务注册中心\u003Cspan class=\&nt\&\u003E&\u002Fname&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c\&\u003E&!-- Spring Boot 启动父依赖 --&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&parent&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&groupId&\u003C\u002Fspan\u003Eorg.springframework.boot\u003Cspan class=\&nt\&\u003E&\u002FgroupId&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&artifactId&\u003C\u002Fspan\u003Espring-boot-starter-parent\u003Cspan class=\&nt\&\u003E&\u002FartifactId&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&version&\u003C\u002Fspan\u003E1.5.4.RELEASE\u003Cspan class=\&nt\&\u003E&\u002Fversion&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&\u002Fparent&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&dependencies&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c\&\u003E&!-- Spring Cloud Netflix Eureka Server 依赖 --&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&dependency&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&groupId&\u003C\u002Fspan\u003Eorg.springframework.cloud\u003Cspan class=\&nt\&\u003E&\u002FgroupId&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&artifactId&\u003C\u002Fspan\u003Espring-cloud-starter-eureka-server\u003Cspan class=\&nt\&\u003E&\u002FartifactId&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&\u002Fdependency&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c\&\u003E&!-- Spring Boot Test 依赖 --&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&dependency&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&groupId&\u003C\u002Fspan\u003Eorg.springframework.boot\u003Cspan class=\&nt\&\u003E&\u002FgroupId&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&artifactId&\u003C\u002Fspan\u003Espring-boot-starter-test\u003Cspan class=\&nt\&\u003E&\u002FartifactId&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&scope&\u003C\u002Fspan\u003Etest\u003Cspan class=\&nt\&\u003E&\u002Fscope&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&\u002Fdependency&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&\u002Fdependencies&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&dependencyManagement&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&dependencies&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c\&\u003E&!-- Spring Cloud Netflix 依赖 --&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&dependency&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&groupId&\u003C\u002Fspan\u003Eorg.springframework.cloud\u003Cspan class=\&nt\&\u003E&\u002FgroupId&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&artifactId&\u003C\u002Fspan\u003Espring-cloud-netflix\u003Cspan class=\&nt\&\u003E&\u002FartifactId&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&version&\u003C\u002Fspan\u003E1.3.1.RELEASE\u003Cspan class=\&nt\&\u003E&\u002Fversion&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&type&\u003C\u002Fspan\u003Epom\u003Cspan class=\&nt\&\u003E&\u002Ftype&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&scope&\u003C\u002Fspan\u003Eimport\u003Cspan class=\&nt\&\u003E&\u002Fscope&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&\u002Fdependency&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&\u002Fdependencies&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&\u002FdependencyManagement&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&build&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&plugins&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&plugin&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&groupId&\u003C\u002Fspan\u003Eorg.apache.maven.plugins\u003Cspan class=\&nt\&\u003E&\u002FgroupId&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&artifactId&\u003C\u002Fspan\u003Emaven-compiler-plugin\u003Cspan class=\&nt\&\u003E&\u002FartifactId&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&configuration&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&source&\u003C\u002Fspan\u003E1.8\u003Cspan class=\&nt\&\u003E&\u002Fsource&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&target&\u003C\u002Fspan\u003E1.8\u003Cspan class=\&nt\&\u003E&\u002Ftarget&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&\u002Fconfiguration&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&\u002Fplugin&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&\u002Fplugins&\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nt\&\u003E&\u002Fbuild&\u003C\u002Fspan\u003E\n\u003Cspan class=\&nt\&\u003E&\u002Fproject&\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E\u003Cbr\u003E使用的依赖是\u003Cbr\u003E– spring-cloud-netflix 1.3.1 是 Spring Cloud Dalston.SR1 版本。\u003Cbr\u003E– spring-cloud-starter-eureka-server Eureka Server 模块依赖\u003Cbr\u003E上面提到的客户端负载均衡 Ribbon ,可以依赖树中看出 spring-cloud-starter-eureka-server 依赖了 Ribbon 相关的库。因为一般 eureka 本身作为服务自注册实现高可用,也可以作为客户端调用其他服务。\u003C\u002Fp\u003E\u003Cp\u003E3. application.yml 配置\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eserver:\n
port: 8888 # 服务端口\neureka:\n
instance:\n
hostname: localhost # 设置主机名\n
registerWithEureka: false # 是否向 Eureka 注册服务。该应用为服务注册中心,不需要自注册,设置为 false\n
fetchRegistry: false
# 是否检索服务。该应用为服务注册中心,职责为注册和发现服务,无需检索服务,设置为 false\n
waitTimeInMsWhenSyncEmpty: 0 # 设置同步为空时的等待时间。默认 5 * MINUTES \n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003Eapplication.property,可以看下面的配置解释:\u003Cbr\u003E– server.port 设置工程服务端口\u003Cbr\u003E– eureka.instance.hostname Eureka 实例主机名\u003Cbr\u003E– eureka.client.registerWithEureka 是否向 Eureka 注册服务。服务注册中心服务,没有作为集群,所以不需要自注册,设置为 false\u003Cbr\u003E– eureka.client.fetchRegistry 是否检索服务。该应用为服务注册中心,职责为注册和发现服务,无需检索服务,设置为 false\u003Cbr\u003E– eureka.server.waitTimeInMsWhenSyncEmpty 设置同步为空时的等待时间。默认 5 * MINUTES\u003C\u002Fp\u003E\u003Cp\u003E4.注册中心应用启动类\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u002F**\n * Spring Boot Eureka Server 应用启动类\n *\n * Created by bysocket on 21\u002F06\u002F17.\n *\u002F\n@EnableEurekaServer
\u002F\u002F Eureka Server 标识\n@SpringBootApplication
\u002F\u002F Spring Boot 应用标识\npublic class EurekaServerApplication {\n
public static void main(String args) {\n
\u002F\u002F 程序启动入口\n
\u002F\u002F 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件\n
SpringApplication.run(EurekaServerApplication.class,args);\n
}\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E@EnableEurekaServer 标志该应用作为 Eureka Server ,并会自动化读取相关配置。\u003C\u002Fp\u003E\u003Ch2\u003E\u003Cb\u003E四、小结\u003C\u002Fb\u003E\u003C\u002Fh2\u003E\u003Cp\u003E此小章节介绍了如何 Eureka 作为服务注册中心 Server,下一小结讲下 服务提供者详解 具体是如何向服务注册中心注册自己的。系列目录如下:\u003C\u002Fp\u003E\u003Cp\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\\u002Farticle\u002F101\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ESpring Cloud Eureka 入门 (一)服务注册中心详解\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003Cbr\u003ESpring Cloud Eureka 入门 (二)服务提供者详解\u003Cbr\u003ESpring Cloud Eureka 入门 (三)服务消费者详解\u003C\u002Fp\u003E\u003Cp\u003E资料:\u003Cbr\u003E《Spring Cloud微服务实战》\u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\\u002Fcps\u002Fitem\u002F.html\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ESpring Cloud微服务实战 计算机与互联网【报价 价格 评论 品牌】-京东热卖\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003Cbr\u003E官方文档\u003Cbr\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\u002Fcloud.spring.io\u002Fspring-cloud-static\u002Fspring-cloud-netflix\u002F1.3.1.RELEASE\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003Ehttp:\u002F\u002Fcloud.spring.io\u002Fspring- … EASE\u002F\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E \u003C\u002Fp\u003E&,&updated&:new Date(&T02:51:51.000Z&),&canComment&:false,&commentPermission&:&anyone&,&commentCount&:0,&collapsedCount&:0,&likeCount&:10,&state&:&published&,&isLiked&:false,&slug&:&&,&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&reviewers&:[],&topics&:[{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&Spring&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&Java&}],&adminClosedComment&:false,&titleImageSize&:{&width&:0,&height&:0},&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&column&:{&slug&:&dreawer&,&name&:&极乐科技&},&tipjarState&:&inactivated&,&annotationAction&:[],&sourceUrl&:&&,&pageCommentsCount&:0,&hasPublishingDraft&:false,&snapshotUrl&:&&,&publishedTime&:&T10:51:51+08:00&,&url&:&\u002Fp\u002F&,&lastestLikers&:[{&bio&:&软件自动化测试&,&isFollowing&:false,&hash&:&d8b83a2201dce689b661ad8f9bd900e5&,&uid&:64,&isOrg&:false,&slug&:&jien-huang&,&isFollowed&:false,&description&:&&,&name&:&Jien Huang&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fjien-huang&,&avatar&:{&id&:&6cd595abc&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&IT狗&,&isFollowing&:false,&hash&:&3b8d6c6b384d139d4f40&,&uid&:84,&isOrg&:false,&slug&:&xeen-king&,&isFollowed&:false,&description&:&&,&name&:&Xeen&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fxeen-king&,&avatar&:{&id&:&17c4dbf23fac71bffe9b94&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&吃乎&,&isFollowing&:false,&hash&:&20d8a8a8f513d07dfd45a0c2a0b75f31&,&uid&:88,&isOrg&:false,&slug&:&zack-wang-86-39&,&isFollowed&:false,&description&:&&,&name&:&Zack Wang&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fzack-wang-86-39&,&avatar&:{&id&:&da8e974dc&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&&,&isFollowing&:false,&hash&:&1af7acfcaeb&,&uid&:20,&isOrg&:false,&slug&:&zhou-xiao-long-27&,&isFollowed&:false,&description&:&应用设计人员&,&name&:&赤虎&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fzhou-xiao-long-27&,&avatar&:{&id&:&v2-decd174201&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&&,&isFollowing&:false,&hash&:&3ca8a5adaa6&,&uid&:719600,&isOrg&:false,&slug&:&yu-ming-jin-6&,&isFollowed&:false,&description&:&大概是只废鱼了&,&name&:&心心念念鱼&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fyu-ming-jin-6&,&avatar&:{&id&:&v2-ec33d657f84c5fdcff511&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}],&summary&:&\u003Cb\u003E本文提纲\u003C\u002Fb\u003E 1. Eureka 服务治理 1.1 什么是 Eureka 1.2 Eureka 集群架构 2. 运行 Eureka 工程 springcloud-eureka-server 3. 详解 Eureka 工程 springcloud-eureka-server \u003Cb\u003E一、Eureka 服务治理\u003C\u002Fb\u003E1.1 什么是 Eureka Eureka,这里是 Spring Cloud Eureka 的简称,…&,&reviewingCommentsCount&:0,&meta&:{&previous&:{&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\\u002F50\u002Fv2-5d7e94cbb44b57b600a5385efe8e35bc_xl.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&topics&:[{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&前端开发&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&JavaScript&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&算法与数据结构&}],&adminClosedComment&:false,&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&author&:{&bio&:&程序员&,&isFollowing&:false,&hash&:&086d2ffcb95d&,&uid&:353200,&isOrg&:false,&slug&:&li-yin-cheng-24&,&isFollowed&:false,&description&:&&,&name&:&李银城&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fli-yin-cheng-24&,&avatar&:{&id&:&3c1a4bab55&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&content&:&\u003Cp\u003E我们已经讨论过了前端与计算机基础的很多话题,诸如\u003Ca href=\&https:\u002F\\u002F?target=http%3A\u002F\\u002F\u002F11\u002Fsql\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ESQL\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E、\u003Ca href=\&https:\u002F\\u002F?target=http%3A\u002F\\u002F\u002F21\u002Fjs-oop\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E面向对象\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E、\u003Ca href=\&https:\u002F\\u002F?target=http%3A\u002F\\u002F\u002F21\u002Fjs-threads\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E多线程\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E,本篇将讨论数据结构与算法,以我接触过的一些例子做为说明。\u003C\u002Fp\u003E\u003Ch2\u003E1. 递归\u003C\u002Fh2\u003E\u003Cp\u003E递归就是自己调自己,递归在前端里面算是一种比较常用的算法。假设现在有一堆数据要处理,要实现上一次请求完成了,才能去调下一个请求。一个是可以用Promise,就像《\u003Ca href=\&https:\u002F\\u002F?target=http%3A\u002F\\u002F\u002F11\u002Fsql\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E前端与SQL\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E》这篇文章里面提到的。但是有时候并不想引入Promise,能简单处理先简单处理。这个时候就可以用递归,如下代码所示:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eids\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E[\u003C\u002Fspan\u003E\u003Cspan class=\&mi\&\u003E3C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&mi\&\u003E9C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&mi\&\u003E6C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E];\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EsendRequest\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eid\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eids\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eshift\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E();\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eid\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003E$\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eajax\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E({\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eurl\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&\u002Fget\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Edata\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eid\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E}}).\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ealways\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c1\&\u003E\u002F\u002Fdo sth.\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Econsole\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Elog\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&finished\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003EsendRequest\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E();\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E});\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Eelse\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Econsole\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Elog\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&finished\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E})();\u003C\u002Fspan\u003E \n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E上面代码定义了一个sendRequest的函数,在请求完成之后再调一下自己。每次调之前先取一个数据,如果数组已经为空,则说明处理完了。这样就用简单的方式实现了串行请求不堵塞的功能。\u003C\u002Fp\u003E\u003Cp\u003E再来讲另外一个场景:DOM树。\u003C\u002Fp\u003E\u003Cp\u003E由于DOM是一棵树,而树的定义本身就是用的递归定义,所以用递归的方法处理树,会非常地简单自然。例如用递归实现一个查DOM的功能document.getElementById。\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EgetElementById\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eid\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E!\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&kc\&\u003Enull\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eid\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E===\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eid\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Efor\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ei\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&mi\&\u003E0\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ei\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E&\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EchildNodes\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Elength\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ei\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E++\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Efound\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EgetElementById\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EchildNodes\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E[\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ei\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E],\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eid\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Efound\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Efound\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&kc\&\u003Enull\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003EgetElementById\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nb\&\u003Edocument\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&d-cal\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003Edocument是DOM树的根结点,一般从document开始往下找。在for循环里面先找document的所有子结点,对所有子结点递归查找他们的子结点,一层一层地往下查找。如果已经到了叶子结点了还没有找到,则在第二行代码的判断里面返回null,返回之后for循环的i加1,继续下一个子结点。如果当前结点的id符合查找条件,则一层层地返回。所以这是一个深度优先的遍历,每次都先从根结点一直往下直到叶子结点,再从下往上返回。\u003C\u002Fp\u003E\u003Cp\u003E最后在控制台验证一下,执行结果如下图所示:\u003C\u002Fp\u003E\u003Cimg src=\&https:\u002F\\u002F50\u002Fv2-2f9ec739ee_b.png\& data-rawwidth=\&319\& data-rawheight=\&48\& class=\&content_image\& width=\&319\&\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E使用递归的优点是代码简单易懂,缺点是效率比不上非递归的实现。Chrome浏览器的查DOM是使用非递归实现。非递归要怎么实现呢?\u003C\u002Fp\u003E\u003Cp\u003E如下代码:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EgetByElementId\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eid\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c1\&\u003E\u002F\u002F遍历所有的Node\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ewhile\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eid\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E===\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eid\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EnextElement\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&kc\&\u003Enull\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E还是依次遍历所有的DOM结点,只是这一次改成一个while循环,函数nextElement负责找到下一个结点。所以关键在于这个nextElement如何非递归实现,如下代码所示:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EnextElement\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Echildren\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Elength\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Echildren\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E[\u003C\u002Fspan\u003E\u003Cspan class=\&mi\&\u003E0\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E];\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EnextElementSibling\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EnextElementSibling\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ewhile\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EparentNode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EparentNode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EnextElementSibling\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EparentNode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EnextElementSibling\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EparentNode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&kc\&\u003Enull\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E还是用深度遍历,先找当前结点的子结点,如果它有子结点,则下一个元素就是它的第一个子结点,否则判断它是否有相邻元素,如果有则返回它的下一个相邻元素。如果它既没有子结点,也没有下一个相邻元素,则要往上返回它的父结点的下一个相邻元素,相当于上面递归实现里面的for循环的i加1.\u003C\u002Fp\u003E\u003Cp\u003E在控制台里面运行这段代码,同样也可以正确地输出结果。不管是非递归还是递归,它们都是深度优先遍历,这个过程如下图所示。\u003C\u002Fp\u003E\u003Cimg src=\&https:\u002F\\u002F50\u002Fv2-03e5e9b258e01f72da09_b.png\& data-rawwidth=\&1294\& data-rawheight=\&950\& class=\&origin_image zh-lightbox-thumb\& width=\&1294\& data-original=\&https:\u002F\\u002F50\u002Fv2-03e5e9b258e01f72da09_r.png\&\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E实际上getElementById浏览器是用的一个哈希map存储的,根据id直接映射到DOM结点,而getElementsByClassName就是用的这样的非递归查找。\u003C\u002Fp\u003E\u003Cp\u003E上面是单个选择器的查找,按id,按class等,多个选择器应该如何查找呢?\u003C\u002Fp\u003E\u003Ch2\u003E2. 复杂选择器的查DOM\u003C\u002Fh2\u003E\u003Cp\u003E如实现一个document.querySelector:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&nb\&\u003Edocument\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EquerySelector\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&.mls-info & div .copyright-content\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E首先把复杂选择器做一个解析,序列为以下格式:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F把selector解析为\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eselectors\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E[\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Erelation\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&descendant\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E
\u003Cspan class=\&nx\&\u003EmatchType\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&class\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Evalue\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&copyright-content\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E},\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Erelation\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&child\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E
\u003Cspan class=\&nx\&\u003EmatchType\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&tag\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E
\u003Cspan class=\&nx\&\u003Evalue\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&div\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E},\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Erelation\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&subSelector\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EmatchType\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&class\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Evalue\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&mls-info\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E}];\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E从右往左,第一个selector是.copyright-content,它是一个类选择器,所以它的matchType是class,它和第二个选择器是祖先和子孙关系,因此它的relation是descendant;同理第二个选择器的matchType是tag,而relation是child,表示是第三个选择器的直接子结点;第三个选择器也是class,但是它没有下一个选择器了,relation用subSelector表示。\u003C\u002Fp\u003E\u003Cp\u003EmatchType的作用就在于用来比较当前选择器是否match,如下代码所示:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ematch\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eselector\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E===\u003C\u002Fspan\u003E \u003Cspan class=\&nb\&\u003Edocument\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&kc\&\u003Efalse\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eswitch\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eselector\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EmatchType\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c1\&\u003E\u002F\u002F如果是类选择器\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ecase\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&class\&\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EclassName\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Etrim\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E().\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Esplit\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&sr\&\u003E\u002F +\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E).\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EindexOf\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eselector\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Evalue\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E&=\u003C\u002Fspan\u003E \u003Cspan class=\&mi\&\u003E0\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&c1\&\u003E\u002F\u002F如果是标签选择器\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ecase\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&tag\&\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EtagName\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EtoLowerCase\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E()\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E===\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eselector\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Evalue\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EtoLowerCase\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E();\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&k\&\u003Edefault\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ethrow\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&unknown selector match type\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E根据不同的matchType做不同的匹配。\u003C\u002Fp\u003E\u003Cp\u003E在匹配的时候,从右往左,依次比较每个选择器是否match. 在比较下一个选择器的时候,需要找到相应的DOM结点,如果当前选择器是下一个选择器的子孙时,则需要比较当前选择器所有的祖先结点,一直往上直到document;而如果是直接子元素的关系,则比较它的父结点即可。所以需要有一个找到下一个目标结点的函数:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EnextTarget\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eselector\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E!\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E||\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E===\u003C\u002Fspan\u003E \u003Cspan class=\&nb\&\u003Edocument\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&kc\&\u003Enull\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eswitch\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eselector\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Erelation\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ecase\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&descendant\&\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EparentNode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EhasNext\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&kc\&\u003Etrue\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E};\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ecase\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&child\&\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EparentNode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EhasNext\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&kc\&\u003Efalse\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E};\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ecase\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&sibling\&\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EpreviousSibling\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EhasNext\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&kc\&\u003Etrue\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E};\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Edefault\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ethrow\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&unknown selector relation type\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c1\&\u003E\u002F\u002FhasNext表示当前选择器relation是否允许继续找下一个节点\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E有了nextTarge和match这两个函数就可以开始遍历DOM,如下代码所示:\u003C\u002Fp\u003E\u003Cimg src=\&https:\u002F\\u002F50\u002Fv2-ac7cd04ead589dbfc8fbd2b_b.png\& data-rawwidth=\&2378\& data-rawheight=\&1730\& class=\&origin_image zh-lightbox-thumb\& width=\&2378\& data-original=\&https:\u002F\\u002F50\u002Fv2-ac7cd04ead589dbfc8fbd2b_r.png\&\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E最外层的while循环和简单选择器一样,都是要遍历所有DOM结点。对于每个结点,先判断第一个选择器是否match,如果不match的话,则继续下一个结点,如果不是标签选择器,对于绝大多数结点将会在这里判断不通过。如果第一个选择器match了,则根据第一个选择器的relation,找到下一个target,判断下一个targe是否match下一个selector,只要有一个target匹配上了,则退出里层的while循环,继续下一个选择器,如果所有的selector都能匹配上说明匹配成功。如果有一个selecotr的所有target都没有match,则说明匹配失败,退出selector的for循环,直接从头开始对下一个DOM结点进行匹配。\u003C\u002Fp\u003E\u003Cp\u003E这样就实现了一个复杂选择器的查DOM。写这个的目的并不是要你自己写一个查DOM的函数拿去用,而是要明白查DOM的过程是怎么样的,可以怎么实现,浏览器又是怎么实现的。还有可以怎么遍历DOM树,当明白这个过程的时候,遇到类似的问题,就可以举一反三。\u003C\u002Fp\u003E\u003Cp\u003E最后在浏览器上运行一下,如下图所示:\u003C\u002Fp\u003E\u003Cimg src=\&https:\u002F\\u002F50\u002Fv2-c443d77d305e529cb473a_b.png\& data-rawwidth=\&1440\& data-rawheight=\&490\& class=\&origin_image zh-lightbox-thumb\& width=\&1440\& data-original=\&https:\u002F\\u002F50\u002Fv2-c443d77d305e529cb473a_r.png\&\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Ch2\u003E3. 重复值处理\u003C\u002Fh2\u003E\u003Cp\u003E现在有个问题,如下图所示:\u003C\u002Fp\u003E\u003Cimg src=\&https:\u002F\\u002F50\u002Fv2-7c246a53ba4a31c58d9fae_b.jpg\& data-rawwidth=\&1089\& data-rawheight=\&350\& class=\&origin_image zh-lightbox-thumb\& width=\&1089\& data-original=\&https:\u002F\\u002F50\u002Fv2-7c246a53ba4a31c58d9fae_r.jpg\&\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E当地图往下拖的时候要更新地图上的房源标签数据,上图绿框表示不变的标签,而黄框表示新加的房源。\u003C\u002Fp\u003E\u003Cp\u003E?后端每次都会把当前地图可见区域的房源返回给我,当用户拖动的时候需要知道哪些是原先已经有的房源,哪些是新加的。把新加的房源画上,而把超出区域的房源删掉,已有的房源保持不动。因此需要对比当前房源和新的结果哪些是重复的。因为如果不这样做的话,改成每次都是全部删掉再重新画,已有的房源标签就会闪一下。因此为了避免闪动做一个增量更新。\u003C\u002Fp\u003E\u003Cp\u003E把这个问题抽象一下就变成:?给两个数组,需要找出第一个数组里面的重复值和非重复值。即有一个数组保存上一次状态的房源,而另一个数组是当前状态的新房源数据。找到的重复值是需要保留,找到非重复值是要删掉的。\u003C\u002Fp\u003E\u003Cp\u003E最直观的方法是使用双重循环。\u003C\u002Fp\u003E\u003Ch2\u003E(1)双重循环\u003C\u002Fh2\u003E\u003Cp\u003E如下代码所示:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003ElastHouses\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E[];\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003EfilterHouse\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ehouses\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003ElastHouses\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E===\u003C\u002Fspan\u003E \u003Cspan class=\&kc\&\u003Enull\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003ElastHouses\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ehouses\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003EremainsHouses\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E[],\u003C\u002Fspan\u003E \n
\u003Cspan class=\&nx\&\u003EnewHouses\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ehouses\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E};\u003C\u002Fspan\u003E
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EremainsHouses\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E[],\u003C\u002Fspan\u003E \n
\u003Cspan class=\&nx\&\u003EnewHouses\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E[];\u003C\u002Fspan\u003E \n\n
\u003Cspan class=\&k\&\u003Efor\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ei\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&mi\&\u003E0\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ei\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E&\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ehouses\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Elength\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ei\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E++\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EisNewHouse\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&kc\&\u003Etrue\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Efor\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ej\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&mi\&\u003E0\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ej\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E&\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003ElastHouses\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Elength\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ej\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E++\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ehouses\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E[\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ei\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E].\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eid\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E===\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003ElastHouses\u003C\u002Fspan\u003E\u003Cspan cla

我要回帖

更多关于 springcloud 服务治理 的文章

 

随机推荐