JS设计模式之订阅发布模式

JavaScript05

JS设计模式之订阅发布模式,第1张

参考我的印象笔记

下面稍微解释一下这个图(框架源码整个过程比较复杂,如果现在看不懂下面几段也没关系,大致了解一下即可)。

我们可以看看 Vue 的源码:

3、发布-订阅模式的优缺点

发布-订阅模式最大的优点就是解耦:

发布-订阅模式也有缺点:

发布-订阅模式和观察者模式

观察者模式与发布-订阅者模式,在平时你可以认为他们是一个东西,但是某些场合(比如面试)下可能需要稍加注意,借用网上一张流行的图:

区别主要在发布-订阅模式中间的这个 Event Channel:

发布-订阅模式和责任链模式

发布-订阅模式和责任链模式也有点类似,主要区别在于:

这个都知道, 一搜一大把, 但是没人讲这三种timeout有什么区别...

源码分析之前先上总结

TCP协议(握手/挥手/发包/丢包重传/滑动窗口/拥塞控制等细节)以及socket属于前置知识, 若不太了解,建议先恶补一下。

以下的源码探究就是罗列记录一下自己的探究过程, 嫌啰嗦可以忽略~

我们知道 okhttp 采用了责任链的设计模式,用一条抽象的 Chain 将一堆 Interceptor 串起来,从发出request 到接收response的路径类似于 node.js 中 koa2 的“洋葱模型”(图1),而 okhttp 的 Interceptor 作用就相当于 koa2 中的 middleware .

“洋葱”的每一层都是一个 Interceptor ,每一层都专注于自己的事情(单一职责),比如日志、mock api,弱网模拟,统一header,APP层缓存、通讯加密等,功能拆分,互不影响,从框架层面来讲也是对AOP思想的具体实践。(AOP可不仅仅是传统意义上的字节码插桩)

okhttp本身已经提供了几个 Interceptor 的默认实现,比如 CacheInterceptor 就是对于http1.1缓存机制的具体实现(cache-controll等) ConnectInterceptor 专门负责创建/复用TCP连接, 里面的 ConnectionPool 就是对 http1.1 中 keep-alive (TCP连接复用)和 pipline 机制(用多条TCP连接实现并发请求)的具体实现。而超时相关的设置也是从这里切入。

上面的 StreamAllocation#newStream 方法就做了两件事,

StreamAllocation#findConnection主要做了两件事,先是从连接池中复用或者创建一个新的连接(RealConnection),然后调用 RealConnection#connect 方法完成 TCP + TLS 握手,其中TCP握手是在

RealConnection#connectSocket(connectTimeout, readTimeout, call, eventListener) 中发起的。

关于 socket.setSoTimeout , 以下是原文档说明的个人翻译及理解

关于 socket.connect(address, connectTimeout)

RealConnection#newCodec() 根据 connection 创建httpCodec(Encodes HTTP requests and decodes HTTP responses.)

当然还有一个地方是在 connectTunnel() 用到, 但是这个前提是走http代理的时候, 这个暂且不详细探究

具体是什么鬼, 看一下source和sink的创建就是知道了

罗列细节之前先总结一下流程:

还是RealConnection的connectSocket方法

Okio.buffer(Source source) 就是 new RealBufferedSource(source)

那么下面主要来看 Okio.source(rawSocket)

跟BuffedSource很相似, 简略描述

同样主要看 Okio.sink(rawSocket) 的实现

sink静态方法的实现

以上~