正式学习React(四) ----Redux源码分析

今天看了下Redux的源码,竟然出奇的简单,好吧。简单翻译做下笔记:

喜欢的同学自己可以去github上看:点这里

createStore.js

  1 import isPlainObject from ‘lodash/isPlainObject‘
  2 import $$observable from ‘symbol-observable‘
  3
  4 /**
  5  * These are private action types reserved by Redux.
  6  * For any unknown actions, you must return the current state.
  7  * If the current state is undefined, you must return the initial state.
  8  * Do not reference these action types directly in your code.
  9  */
 10 export var ActionTypes = {
 11   INIT: ‘@@redux/INIT‘
 12 }
 13
 14 /**
 15  * Creates a Redux store that holds the state tree.
 16  * The only way to change the data in the store is to call `dispatch()` on it.
 17  *
 18  * There should only be a single store in your app. To specify how different
 19  * parts of the state tree respond to actions, you may combine several reducers
 20  * into a single reducer function by using `combineReducers`.
 21  *
 22  * @param {Function} reducer A function that returns the next state tree, given
 23  * the current state tree and the action to handle.
 24  *
 25  * @param {any} [preloadedState] The initial state. You may optionally specify it
 26  * to hydrate the state from the server in universal apps, or to restore a
 27  * previously serialized user session.
 28  * If you use `combineReducers` to produce the root reducer function, this must be
 29  * an object with the same shape as `combineReducers` keys.
 30  *
 31  * @param {Function} [enhancer] The store enhancer. You may optionally specify it
 32  * to enhance the store with third-party capabilities such as middleware,
 33  * time travel, persistence, etc. The only store enhancer that ships with Redux
 34  * is `applyMiddleware()`.
 35  *
 36  * @returns {Store} A Redux store that lets you read the state, dispatch actions
 37  * and subscribe to changes.
 38  */
 39 export default function createStore(reducer, preloadedState, enhancer) {

//如果没有提供初始的state,提供了enhancer,就将初试state置为undefined

40   if (typeof preloadedState === ‘function‘ && typeof enhancer === ‘undefined‘) {
 41     enhancer = preloadedState
 42     preloadedState = undefined
 43   }
 44 

//确保enhancer一定是函数
 45   if (typeof enhancer !== ‘undefined‘) {
 46     if (typeof enhancer !== ‘function‘) {
 47       throw new Error(‘Expected the enhancer to be a function.‘)
 48     }
 49      //这个会返回一个store,只不过是增强版的。
 50     return enhancer(createStore)(reducer, preloadedState)
 51   }
 52 
 53   if (typeof reducer !== ‘function‘) {
 54     throw new Error(‘Expected the reducer to be a function.‘)
 55   }
 56 

//初始化一些变量,用作闭包。
 57   var currentReducer = reducer
 58   var currentState = preloadedState    //undefined || 传进来的初始值
 59   var currentListeners = []
 60   var nextListeners = currentListeners
 61   var isDispatching = false
 62 

//这个辅助函数是这样的,如果你没有调用dispacth,那么每次调用subscribe来添加监听器的都会被push到nextListenrs,他是currentListerns的一个副本。

//总的来说这个函数的意义我个人觉得就是保护了currentListeners不被随意污染.保证每次dispacth前状态不变。
 63   function ensureCanMutateNextListeners() {
 64     if (nextListeners === currentListeners) {
 65       nextListeners = currentListeners.slice()
 66     }
 67   }
 68
 69   /**
 70    * Reads the state tree managed by the store.
 71    *
 72    * @returns {any} The current state tree of your application.
 73    */       //这个就是返回当前的state
 74   function getState() {
 75     return currentState
 76   }
 77
 78   /**
 79    * Adds a change listener. It will be called any time an action is dispatched,
 80    * and some part of the state tree may potentially have changed. You may then
 81    * call `getState()` to read the current state tree inside the callback.
 82    *
 83    * You may call `dispatch()` from a change listener, with the following
 84    * caveats:
 85    *
 86    * 1. The subscriptions are snapshotted just before every `dispatch()` call.
 87    * If you subscribe or unsubscribe while the listeners are being invoked, this
 88    * will not have any effect on the `dispatch()` that is currently in progress.
 89    * However, the next `dispatch()` call, whether nested or not, will use a more
 90    * recent snapshot of the subscription list.
 91    *
 92    * 2. The listener should not expect to see all state changes, as the state
 93    * might have been updated multiple times during a nested `dispatch()` before
 94    * the listener is called. It is, however, guaranteed that all subscribers
 95    * registered before the `dispatch()` started will be called with the latest
 96    * state by the time it exits.
 97    *
 98    * @param {Function} listener A callback to be invoked on every dispatch.
 99    * @returns {Function} A function to remove this change listener.
100    */

//简单点说就是 设置监听函数,每次dispatch(action)的时候,这些传进去的listenr们就会全部被调用
101   function subscribe(listener) {
102     if (typeof listener !== ‘function‘) {
103       throw new Error(‘Expected listener to be a function.‘)
104     }
105
106     var isSubscribed = true
107
108     ensureCanMutateNextListeners()
109     nextListeners.push(listener)
110
111     return function unsubscribe() {
112       if (!isSubscribed) {
113         return
114       }
115
116       isSubscribed = false
117
118       ensureCanMutateNextListeners()
119       var index = nextListeners.indexOf(listener)
120       nextListeners.splice(index, 1)
121     }
122   }
123
124   /**
125    * Dispatches an action. It is the only way to trigger a state change.
126    *
127    * The `reducer` function, used to create the store, will be called with the
128    * current state tree and the given `action`. Its return value will
129    * be considered the **next** state of the tree, and the change listeners
130    * will be notified.
131    *
132    * The base implementation only supports plain object actions. If you want to
133    * dispatch a Promise, an Observable, a thunk, or something else, you need to
134    * wrap your store creating function into the corresponding middleware. For
135    * example, see the documentation for the `redux-thunk` package. Even the
136    * middleware will eventually dispatch plain object actions using this method.
137    *
138    * @param {Object} action A plain object representing “what changed”. It is
139    * a good idea to keep actions serializable so you can record and replay user
140    * sessions, or use the time travelling `redux-devtools`. An action must have
141    * a `type` property which may not be `undefined`. It is a good idea to use
142    * string constants for action types.
143    *
144    * @returns {Object} For convenience, the same action object you dispatched.
145    *
146    * Note that, if you use a custom middleware, it may wrap `dispatch()` to
147    * return something else (for example, a Promise you can await).
148    */

//通知store,我要更新state了。
149   function dispatch(action) {
150     if (!isPlainObject(action)) {
151       throw new Error(
152         ‘Actions must be plain objects. ‘ +
153         ‘Use custom middleware for async actions.‘
154       )
155     }
156
157     if (typeof action.type === ‘undefined‘) {
158       throw new Error(
159         ‘Actions may not have an undefined "type" property. ‘ +
160         ‘Have you misspelled a constant?‘
161       )
162     }
163
164     if (isDispatching) {
165       throw new Error(‘Reducers may not dispatch actions.‘)
166     }
167
168     try {
169       isDispatching = true
170       currentState = currentReducer(currentState, action)
171     } finally {
172       isDispatching = false
173     }
174
175     var listeners = currentListeners = nextListeners
176     for (var i = 0; i < listeners.length; i++) {
177       var listener = listeners[i]
178       listener()
179     }
180
181     return action
182   }
183
184   /**
185    * Replaces the reducer currently used by the store to calculate the state.
186    *
187    * You might need this if your app implements code splitting and you want to
188    * load some of the reducers dynamically. You might also need this if you
189    * implement a hot reloading mechanism for Redux.
190    *
191    * @param {Function} nextReducer The reducer for the store to use instead.
192    * @returns {void}
193    */

//重置reducer,然后初始化state
194   function replaceReducer(nextReducer) {
195     if (typeof nextReducer !== ‘function‘) {
196       throw new Error(‘Expected the nextReducer to be a function.‘)
197     }
198
199     currentReducer = nextReducer
200     dispatch({ type: ActionTypes.INIT })
201   }
202
203   /**
204    * Interoperability point for observable/reactive libraries.
205    * @returns {observable} A minimal observable of state changes.
206    * For more information, see the observable proposal:
207    * https://github.com/zenparsing/es-observable
208    */

//暂时我还不知道这个有什么吊用,先不管好了。
209   function observable() {
210     var outerSubscribe = subscribe
211     return {
212       /**
213        * The minimal observable subscription method.
214        * @param {Object} observer Any object that can be used as an observer.
215        * The observer object should have a `next` method.
216        * @returns {subscription} An object with an `unsubscribe` method that can
217        * be used to unsubscribe the observable from the store, and prevent further
218        * emission of values from the observable.
219        */
220       subscribe(observer) {
221         if (typeof observer !== ‘object‘) {
222           throw new TypeError(‘Expected the observer to be an object.‘)
223         }
224
225         function observeState() {
226           if (observer.next) {
227             observer.next(getState())
228           }
229         }
230
231         observeState()
232         var unsubscribe = outerSubscribe(observeState)
233         return { unsubscribe }
234       },
235
236       [$$observable]() {
237         return this
238       }
239     }
240   }
241
242   // When a store is created, an "INIT" action is dispatched so that every
243   // reducer returns their initial state. This effectively populates
244   // the initial state tree.

//给currentState设定初始状态
245   dispatch({ type: ActionTypes.INIT })
246
247   return {
248     dispatch,
249     subscribe,
250     getState,
251     replaceReducer,
252     [$$observable]: observable
253   }
254 }

关于 createStore,我们就关注它返回的对象,subscribe是订阅监听函数的,getState是返回state的,dispacth是发布消息的,更新state的。

剩下那2个就不管他算了。

combineReducers.js

  1 import { ActionTypes } from ‘./createStore‘
  2 import isPlainObject from ‘lodash/isPlainObject‘
  3 import warning from ‘./utils/warning‘
  4
  5 var NODE_ENV = typeof process !== ‘undefined‘ ? process.env.NODE_ENV : ‘development‘
  6
  7 function getUndefinedStateErrorMessage(key, action) {
  8   var actionType = action && action.type
  9   var actionName = actionType && `"${actionType.toString()}"` || ‘an action‘
 10
 11   return (
 12     `Given action ${actionName}, reducer "${key}" returned undefined. ` +
 13     `To ignore an action, you must explicitly return the previous state.`
 14   )
 15 }
 16
 17 function getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {
 18   var reducerKeys = Object.keys(reducers)
 19   var argumentName = action && action.type === ActionTypes.INIT ?
 20     ‘preloadedState argument passed to createStore‘ :
 21     ‘previous state received by the reducer‘
 22
 23   if (reducerKeys.length === 0) {
 24     return (
 25       ‘Store does not have a valid reducer. Make sure the argument passed ‘ +
 26       ‘to combineReducers is an object whose values are reducers.‘
 27     )
 28   }
 29
 30   if (!isPlainObject(inputState)) {
 31     return (
 32       `The ${argumentName} has unexpected type of "` +
 33       ({}).toString.call(inputState).match(/\s([a-z|A-Z]+)/)[1] +
 34       `". Expected argument to be an object with the following ` +
 35       `keys: "${reducerKeys.join(‘", "‘)}"`
 36     )
 37   }
 38
 39   var unexpectedKeys = Object.keys(inputState).filter(key =>
 40     !reducers.hasOwnProperty(key) &&
 41     !unexpectedKeyCache[key]
 42   )
 43
 44   unexpectedKeys.forEach(key => {
 45     unexpectedKeyCache[key] = true
 46   })
 47
 48   if (unexpectedKeys.length > 0) {
 49     return (
 50       `Unexpected ${unexpectedKeys.length > 1 ? ‘keys‘ : ‘key‘} ` +
 51       `"${unexpectedKeys.join(‘", "‘)}" found in ${argumentName}. ` +
 52       `Expected to find one of the known reducer keys instead: ` +
 53       `"${reducerKeys.join(‘", "‘)}". Unexpected keys will be ignored.`
 54     )
 55   }
 56 }
 57 

58 function assertReducerSanity(reducers) {
 59   Object.keys(reducers).forEach(key => {
 60     var reducer = reducers[key]
 61     var initialState = reducer(undefined, { type: ActionTypes.INIT })
 62
 63     if (typeof initialState === ‘undefined‘) {
 64       throw new Error(
 65         `Reducer "${key}" returned undefined during initialization. ` +
 66         `If the state passed to the reducer is undefined, you must ` +
 67         `explicitly return the initial state. The initial state may ` +
 68         `not be undefined.`
 69       )
 70     }
 71
 72     var type = ‘@@redux/PROBE_UNKNOWN_ACTION_‘ + Math.random().toString(36).substring(7).split(‘‘).join(‘.‘)
 73     if (typeof reducer(undefined, { type }) === ‘undefined‘) {
 74       throw new Error(
 75         `Reducer "${key}" returned undefined when probed with a random type. ` +
 76         `Don‘t try to handle ${ActionTypes.INIT} or other actions in "redux/*" ` +
 77         `namespace. They are considered private. Instead, you must return the ` +
 78         `current state for any unknown actions, unless it is undefined, ` +
 79         `in which case you must return the initial state, regardless of the ` +
 80         `action type. The initial state may not be undefined.`
 81       )
 82     }
 83   })
 84 }
 85
 86 /**
 87  * Turns an object whose values are different reducer functions, into a single
 88  * reducer function. It will call every child reducer, and gather their results
 89  * into a single state object, whose keys correspond to the keys of the passed
 90  * reducer functions.
 91  *
 92  * @param {Object} reducers An object whose values correspond to different
 93  * reducer functions that need to be combined into one. One handy way to obtain
 94  * it is to use ES6 `import * as reducers` syntax. The reducers may never return
 95  * undefined for any action. Instead, they should return their initial state
 96  * if the state passed to them was undefined, and the current state for any
 97  * unrecognized action.
 98  *
 99  * @returns {Function} A reducer function that invokes every reducer inside the
100  * passed object, and builds a state object with the same shape.
101  */
102 export default function combineReducers(reducers) {
103   var reducerKeys = Object.keys(reducers)
104   var finalReducers = {}

105   for (var i = 0; i < reducerKeys.length; i++) {
106     var key = reducerKeys[i]
107
108     if (NODE_ENV !== ‘production‘) {

//排除undefined.
109       if (typeof reducers[key] === ‘undefined‘) {
110         warning(`No reducer provided for key "${key}"`)
111       }
112     }
113    

//排除不是func的
114     if (typeof reducers[key] === ‘function‘) {
115       finalReducers[key] = reducers[key]
116     }
117   }
118   var finalReducerKeys = Object.keys(finalReducers)
119
120   if (NODE_ENV !== ‘production‘) {
121     var unexpectedKeyCache = {}
122   }
123
124   var sanityError
125   try {        //这里会对每个子reducer的state进行检查。返回不能为undefined
126     assertReducerSanity(finalReducers)
127   } catch (e) {
128     sanityError = e
129   }
130 

//我们最最关心的就是这个返回函数,其实我们如果已经堆这个函数有一定的了解,就知道这个函数其实就把子reducers全部在这个函数里执行一边,      //返回最后的state
131   return function combination(state = {}, action) {
132     if (sanityError) {
133       throw sanityError
134     }
135
136     if (NODE_ENV !== ‘production‘) {
137       var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache)
138       if (warningMessage) {
139         warning(warningMessage)
140       }
141     }
142
143     var hasChanged = false
144     var nextState = {}
145     for (var i = 0; i < finalReducerKeys.length; i++) {
146       var key = finalReducerKeys[i]
147       var reducer = finalReducers[key]
148       var previousStateForKey = state[key]
149       var nextStateForKey = reducer(previousStateForKey, action)
150       if (typeof nextStateForKey === ‘undefined‘) {
151         var errorMessage = getUndefinedStateErrorMessage(key, action)
152         throw new Error(errorMessage)
153       }
154       nextState[key] = nextStateForKey
155       hasChanged = hasChanged || nextStateForKey !== previousStateForKey
156     }
157     return hasChanged ? nextState : state
158   }
159 }

compose.js

 1 /**
 2  * Composes single-argument functions from right to left. The rightmost
 3  * function can take multiple arguments as it provides the signature for
 4  * the resulting composite function.
 5  *
 6  * @param {...Function} funcs The functions to compose.
 7  * @returns {Function} A function obtained by composing the argument functions
 8  * from right to left. For example, compose(f, g, h) is identical to doing
 9  * (...args) => f(g(h(...args))).
10  */
11
12 export default function compose(...funcs) {
13
14      //funcs就是我们传入的中间件,fn1,fn2...
15      //如果什么都没有,就返回一个function(arg){return arg};当作默认的中间件
16   if (funcs.length === 0) {
17     return arg => arg
18   }
19
20
21      //排除所有中间件参数中不是function的
22   funcs = funcs.filter(func => typeof func === ‘function‘)
23
24
25       //如果只有一个中间件参数,就把这个唯一的中间件返回。
26   if (funcs.length === 1) {
27     return funcs[0]
28   }
29
30      //如果中间件参数个数超过1个
31
32      //取出最后一个中间件参数
33   const last = funcs[funcs.length - 1]
34
35      //将funcs中最开头到倒数第二个的数组复制一份,即排除了最后一个中间件
36   const rest = funcs.slice(0, -1)
37
38
39   //返回(...args) => f(g(h(...args))).
40   return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args))
41 }

解释完compose.js,我们可以简单的理解为: compose就是用来将函数组合起来使用。

 假如:compose(f, g, h)
 分装后:(...args) => f(g(h(...args))).

applyMiddleware.js

 1 import compose from ‘./compose‘
 2
 3 /**
 4  * Creates a store enhancer that applies middleware to the dispatch method
 5  * of the Redux store. This is handy for a variety of tasks, such as expressing
 6  * asynchronous actions in a concise manner, or logging every action payload.
 7  *
 8  * See `redux-thunk` package as an example of the Redux middleware.
 9  *
10  * Because middleware is potentially asynchronous, this should be the first
11  * store enhancer in the composition chain.
12  *
13  * Note that each middleware will be given the `dispatch` and `getState` functions
14  * as named arguments.
15  *
16  * @param {...Function} middlewares The middleware chain to be applied.
17  * @returns {Function} A store enhancer applying the middleware.
18  */
19 export default function applyMiddleware(...middlewares) {

//短短几行,很简单哟。     //返回我们在creteStore里看到的enhancer
20   return (createStore) => (reducer, preloadedState, enhancer) => {
21     var store = createStore(reducer, preloadedState, enhancer)
22     var dispatch = store.dispatch
23     var chain = []
24
25     var middlewareAPI = {
26       getState: store.getState,
27       dispatch: (action) => dispatch(action)
28     }

//将 当前store的getState和dispacth方法挂载到中间件里。
29     chain = middlewares.map(middleware => middleware(middlewareAPI))
30     dispatch = compose(...chain)(store.dispatch)
31
32     return {
33       ...store,
34       dispatch
35     }
36   }
37 }

假如我们在代码里看到:

const store =  applyMiddleware(promise, thunk, observable)(createStore)(reducer);亦或是

const store = createStore(
reducer,state,applyMiddleware(promise, thunk, observable)
);
我们根据上面的代码走一遍,看看是怎么个执行过程。

1: applyMiddleware(promise, thunk, observable) 会返回enhancer.
2:enhancer(createStore) 返回一个将中间件参数都闭包进来的 createStore函数,此时我们叫他加强版!我给他标注是红色;

3:createStore(reducer) 然后就是上面代码的21-34行。 最后我们关心一下这个返回的store里的dispatch,其实是加强版的,因为里面是执行中间件的!!但是中间件里面到底干了什么,我们目前不得而知,总之记住,dispacth现在牛逼了就行。比如可以处理异步啦等等。
bindActionCreators.js

 1 function bindActionCreator(actionCreator, dispatch) {
 2   return (...args) => dispatch(actionCreator(...args))
 3 }
 4
 5 /**
 6  * Turns an object whose values are action creators, into an object with the
 7  * same keys, but with every function wrapped into a `dispatch` call so they
 8  * may be invoked directly. This is just a convenience method, as you can call
 9  * `store.dispatch(MyActionCreators.doSomething())` yourself just fine.
10  *
11  * For convenience, you can also pass a single function as the first argument,
12  * and get a function in return.
13  *
14  * @param {Function|Object} actionCreators An object whose values are action
15  * creator functions. One handy way to obtain it is to use ES6 `import * as`
16  * syntax. You may also pass a single function.
17  *
18  * @param {Function} dispatch The `dispatch` function available on your Redux
19  * store.
20  *
21  * @returns {Function|Object} The object mimicking the original object, but with
22  * every action creator wrapped into the `dispatch` call. If you passed a
23  * function as `actionCreators`, the return value will also be a single
24  * function.
25  */
26 export default function bindActionCreators(actionCreators, dispatch) {
27   if (typeof actionCreators === ‘function‘) {
28     return bindActionCreator(actionCreators, dispatch)
29   }
30
31   if (typeof actionCreators !== ‘object‘ || actionCreators === null) {
32     throw new Error(
33       `bindActionCreators expected an object or a function, instead received ${actionCreators === null ? ‘null‘ : typeof actionCreators}. ` +
34       `Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?`
35     )
36   }
37
38   var keys = Object.keys(actionCreators)
39   var boundActionCreators = {}
40   for (var i = 0; i < keys.length; i++) {
41     var key = keys[i]
42     var actionCreator = actionCreators[key]
43     if (typeof actionCreator === ‘function‘) {
44       boundActionCreators[key] = bindActionCreator(actionCreator, dispatch)
45     }
46   }
47   return boundActionCreators
48 }

这个东西唯一的好处是往下传actionCreator和dispatch的时候,少些代码,无形中在props里加了内容!!!!

具体应用场景,大家自行谷歌。因为我也才学这个第8天,这函数我自己都没用过····哈哈。不过以后肯定要用了!!!

代码十分简单,我就不分析了。

这里有一篇园内的朋友写的它的应用,凑合看吧:点这里



时间: 2024-10-08 06:14:55

正式学习React(四) ----Redux源码分析的相关文章

正式学习React(五) react-redux源码分析

磨刀不误砍柴工,咱先把react-redux里的工具函数分析一下: 源码点这里  shallowEqual.js 1 export default function shallowEqual(objA, objB) { 2 if (objA === objB) { 3 return true 4 } 5 6 const keysA = Object.keys(objA) 7 const keysB = Object.keys(objB) 8 9 if (keysA.length !== keys

EasyUI学习总结(四)——parser源码分析

EasyUI学习总结(四)--parser源码分析 parser模块是easyloader第一个加载的模块,它的主要作用,就是扫描页面上easyui开头的class标签,然后初始化成easyui控件. 1 /** 2 * parser模块主要是解析页面中easyui的控件 3 */ 4 $.parser = { 5 // 是否自动解析 6 auto: true, 7 8 // 可以被解析的控件 9 plugins:['linkbutton','menu','menubutton','splitb

Redux源码分析之compose

Redux源码分析之基本概念 Redux源码分析之createStore Redux源码分析之bindActionCreators Redux源码分析之combineReducers Redux源码分析之compose      解读之前先了准备一下基本知识 rest参数  形式为...变量名,用于获取函数的多余参数 ,该变量将多余的参数放入数组中, 只能是参数的最后一个. 扩展运算符 扩展运算符(spread)是三个点(...).它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序

u-boot学习(三):u-boot源码分析

建立域模型和关系数据模型有着不同的出发点: 域模型: 由程序代码组成, 通过细化持久化类的的粒度可提高代码的可重用性, 简化编程 在没有数据冗余的情况下, 应该尽可能减少表的数目, 简化表之间的参照关系, 以便提高数据的访问速度 Hibernate 把持久化类的属性分为两种: 值(value)类型: 没有 OID, 不能被单独持久化, 生命周期依赖于所属的持久化类的对象的生命周期 实体(entity)类型: 有 OID, 可以被单独持久化, 有独立的生命周期(如果实体类型包含值类型,这个值类型就

EasyUI学习总结(三)——easyloader源码分析

EasyUI学习总结(三)--easyloader源码分析 easyloader模块是用来加载jquery easyui的js和css文件的,而且它可以分析模块的依赖关系,先加载依赖项.模块加载好了会调用parse模块来解析页面.把class是easyui开头的标签都转化成easyui的控件. 先看Demo1例子,再分析源代码. 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>easyloader范例</tit

memcached学习笔记——存储命令源码分析下篇

上一篇回顾:<memcached学习笔记——存储命令源码分析上篇>通过分析memcached的存储命令源码的过程,了解了memcached如何解析文本命令和mencached的内存管理机制. 本文是延续上一篇,继续分析存储命令的源码.接上一篇内存分配成功后,本文主要讲解:1.memcached存储方式:2.add和set命令的区别. memcached存储方式 哈希表(HashTable) 哈希表在实践中使用的非常广泛,例如编译器通常会维护的一个符号表来保存标记,很多高级语言中也显式的支持哈希

memcached学习笔记——存储命令源码分析上

原创文章,转载请标明,谢谢. 上一篇分析过memcached的连接模型,了解memcached是如何高效处理客户端连接,这一篇分析memcached源码中的process_update_command函数,探究memcached客户端的set命令,解读memcached是如何解析客户端文本命令,剖析memcached的内存管理,LRU算法是如何工作等等. 解析客户端文本命令 客户端向memcached server发出set操作,memcached server读取客户端的命令,客户端的连接状态

【React Native】源码分析之Native UI的封装和管理

??ReactNative作为使用React开发Native应用的新框架,随着时间的增加,无论是社区还是个人对她的兴趣与日递增.此文目的是希望和大家一起欣赏一下ReactNative的部分源码.阅读源码好处多多,让攻城狮更溜的开发ReactNative应用的同时,也能梳理RN项目的设计思路,增加自己的内功修为,^_^. ??好的,就让我们轻松的开始吧.此篇是以Android平台源码分析为主,分享Native UI的封装和管理,重点涉及react-native源码中com.facebook.rea

Hadoop-2.4.1学习之NameNode -format源码分析

在Hadoop-2.X中,使用hdfs namenode –format对文件系统进行格式化.虽然无论是在生产环境还是测试环境中,已经使用了该命令若干次了,也大体了解该命令就是在本地文件系统中创建几个文件夹,但具体是如何执行的则需要通过阅读源代码来了解了. 要想看到该命令的源代码,需要看看hdfs脚本中是如何执行相应的java类的.在hdfs脚本中,下面的语句说明了实际执行的java类和参数,其中类为org.apache.hadoop.hdfs.server.namenode.NameNode,