今天看了下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) {
  40.  
  41. //如果没有提供初始的state,提供了enhancer,就将初试state置为undefined
  42.  
  43. if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
  44. enhancer = preloadedState
  45. preloadedState = undefined
  46. }
  47.  
  48. //确保enhancer一定是函数
  49. if (typeof enhancer !== 'undefined') {
  50. if (typeof enhancer !== 'function') {
  51. throw new Error('Expected the enhancer to be a function.')
  52. }
  53. //这个会返回一个store,只不过是增强版的。
  54. return enhancer(createStore)(reducer, preloadedState)
  55. }


  56. if (typeof reducer !== 'function') {
  57. throw new Error('Expected the reducer to be a function.')
  58. }
  59.  
  60. //初始化一些变量,用作闭包。
  61. var currentReducer = reducer
  62. var currentState = preloadedState //undefined || 传进来的初始值
  63. var currentListeners = []
  64. var nextListeners = currentListeners
  65. var isDispatching = false
  66.  
  67. //这个辅助函数是这样的,如果你没有调用dispacth,那么每次调用subscribe来添加监听器的都会被push到nextListenrs,他是currentListerns的一个副本。
  68.  
  69. //总的来说这个函数的意义我个人觉得就是保护了currentListeners不被随意污染.保证每次dispacth前状态不变。
  70. function ensureCanMutateNextListeners() {
  71. if (nextListeners === currentListeners) {
  72. nextListeners = currentListeners.slice()
  73. }
  74. }
  75.  
  76. /**
  77. * Reads the state tree managed by the store.
  78. *
  79. * @returns {any} The current state tree of your application.
  80. */
    //这个就是返回当前的state
  81. function getState() {
  82. return currentState
  83. }
  84.  
  85. /**
  86. * Adds a change listener. It will be called any time an action is dispatched,
  87. * and some part of the state tree may potentially have changed. You may then
  88. * call `getState()` to read the current state tree inside the callback.
  89. *
  90. * You may call `dispatch()` from a change listener, with the following
  91. * caveats:
  92. *
  93. * 1. The subscriptions are snapshotted just before every `dispatch()` call.
  94. * If you subscribe or unsubscribe while the listeners are being invoked, this
  95. * will not have any effect on the `dispatch()` that is currently in progress.
  96. * However, the next `dispatch()` call, whether nested or not, will use a more
  97. * recent snapshot of the subscription list.
  98. *
  99. * 2. The listener should not expect to see all state changes, as the state
  100. * might have been updated multiple times during a nested `dispatch()` before
  101. * the listener is called. It is, however, guaranteed that all subscribers
  102. * registered before the `dispatch()` started will be called with the latest
  103. * state by the time it exits.
  104. *
  105. * @param {Function} listener A callback to be invoked on every dispatch.
  106. * @returns {Function} A function to remove this change listener.
  107. */
  108.  
  109. //简单点说就是 设置监听函数,每次dispatch(action)的时候,这些传进去的listenr们就会全部被调用
  110. function subscribe(listener) {
  111. if (typeof listener !== 'function') {
  112. throw new Error('Expected listener to be a function.')
  113. }
  114.  
  115. var isSubscribed = true
  116.  
  117. ensureCanMutateNextListeners()
  118. nextListeners.push(listener)
  119.  
  120. return function unsubscribe() {
  121. if (!isSubscribed) {
  122. return
  123. }
  124.  
  125. isSubscribed = false
  126.  
  127. ensureCanMutateNextListeners()
  128. var index = nextListeners.indexOf(listener)
  129. nextListeners.splice(index, 1)
  130. }
  131. }
  132.  
  133. /**
  134. * Dispatches an action. It is the only way to trigger a state change.
  135. *
  136. * The `reducer` function, used to create the store, will be called with the
  137. * current state tree and the given `action`. Its return value will
  138. * be considered the **next** state of the tree, and the change listeners
  139. * will be notified.
  140. *
  141. * The base implementation only supports plain object actions. If you want to
  142. * dispatch a Promise, an Observable, a thunk, or something else, you need to
  143. * wrap your store creating function into the corresponding middleware. For
  144. * example, see the documentation for the `redux-thunk` package. Even the
  145. * middleware will eventually dispatch plain object actions using this method.
  146. *
  147. * @param {Object} action A plain object representing “what changed”. It is
  148. * a good idea to keep actions serializable so you can record and replay user
  149. * sessions, or use the time travelling `redux-devtools`. An action must have
  150. * a `type` property which may not be `undefined`. It is a good idea to use
  151. * string constants for action types.
  152. *
  153. * @returns {Object} For convenience, the same action object you dispatched.
  154. *
  155. * Note that, if you use a custom middleware, it may wrap `dispatch()` to
  156. * return something else (for example, a Promise you can await).
  157. */
  158.  
  159. //通知store,我要更新state了。
  160. function dispatch(action) {
  161. if (!isPlainObject(action)) {
  162. throw new Error(
  163. 'Actions must be plain objects. ' +
  164. 'Use custom middleware for async actions.'
  165. )
  166. }
  167.  
  168. if (typeof action.type === 'undefined') {
  169. throw new Error(
  170. 'Actions may not have an undefined "type" property. ' +
  171. 'Have you misspelled a constant?'
  172. )
  173. }
  174.  
  175. if (isDispatching) {
  176. throw new Error('Reducers may not dispatch actions.')
  177. }
  178.  
  179. try {
  180. isDispatching = true
  181. currentState = currentReducer(currentState, action)
  182. } finally {
  183. isDispatching = false
  184. }
  185.  
  186. var listeners = currentListeners = nextListeners
  187. for (var i = 0; i < listeners.length; i++) {
  188. var listener = listeners[i]
  189. listener()
  190. }
  191.  
  192. return action
  193. }
  194.  
  195. /**
  196. * Replaces the reducer currently used by the store to calculate the state.
  197. *
  198. * You might need this if your app implements code splitting and you want to
  199. * load some of the reducers dynamically. You might also need this if you
  200. * implement a hot reloading mechanism for Redux.
  201. *
  202. * @param {Function} nextReducer The reducer for the store to use instead.
  203. * @returns {void}
  204. */
  205.  
  206. //重置reducer,然后初始化state
  207. function replaceReducer(nextReducer) {
  208. if (typeof nextReducer !== 'function') {
  209. throw new Error('Expected the nextReducer to be a function.')
  210. }
  211.  
  212. currentReducer = nextReducer
  213. dispatch({ type: ActionTypes.INIT })
  214. }
  215.  
  216. /**
  217. * Interoperability point for observable/reactive libraries.
  218. * @returns {observable} A minimal observable of state changes.
  219. * For more information, see the observable proposal:
  220. * https://github.com/zenparsing/es-observable
  221. */
  222.  
  223. //暂时我还不知道这个有什么吊用,先不管好了。
  224. function observable() {
  225. var outerSubscribe = subscribe
  226. return {
  227. /**
  228. * The minimal observable subscription method.
  229. * @param {Object} observer Any object that can be used as an observer.
  230. * The observer object should have a `next` method.
  231. * @returns {subscription} An object with an `unsubscribe` method that can
  232. * be used to unsubscribe the observable from the store, and prevent further
  233. * emission of values from the observable.
  234. */
  235. subscribe(observer) {
  236. if (typeof observer !== 'object') {
  237. throw new TypeError('Expected the observer to be an object.')
  238. }
  239.  
  240. function observeState() {
  241. if (observer.next) {
  242. observer.next(getState())
  243. }
  244. }
  245.  
  246. observeState()
  247. var unsubscribe = outerSubscribe(observeState)
  248. return { unsubscribe }
  249. },
  250.  
  251. [$$observable]() {
  252. return this
  253. }
  254. }
  255. }
  256.  
  257. // When a store is created, an "INIT" action is dispatched so that every
  258. // reducer returns their initial state. This effectively populates
  259. // the initial state tree.
  260.  
  261. //给currentState设定初始状态
  262. dispatch({ type: ActionTypes.INIT })
  263.  
  264. return {
  265. dispatch,
  266. subscribe,
  267. getState,
  268. replaceReducer,
  269. [$$observable]: observable
  270. }
  271. }

关于 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.  
  106. for (var i = 0; i < reducerKeys.length; i++) {
  107. var key = reducerKeys[i]
  108.  
  109. if (NODE_ENV !== 'production') {
  110.  
  111. //排除undefined.
  112. if (typeof reducers[key] === 'undefined') {
  113. warning(`No reducer provided for key "${key}"`)
  114. }
  115. }
  116.  
  117. //排除不是func的
  118. if (typeof reducers[key] === 'function') {
  119. finalReducers[key] = reducers[key]
  120. }
  121. }
  122. var finalReducerKeys = Object.keys(finalReducers)
  123.  
  124. if (NODE_ENV !== 'production') {
  125. var unexpectedKeyCache = {}
  126. }
  127.  
  128. var sanityError
  129. try {
    //这里会对每个子reducer的state进行检查。返回不能为undefined
  130. assertReducerSanity(finalReducers)
  131. } catch (e) {
  132. sanityError = e
  133. }
  134.  
  135. //我们最最关心的就是这个返回函数,其实我们如果已经堆这个函数有一定的了解,就知道这个函数其实就把子reducers全部在这个函数里执行一边,
    //返回最后的state
  136. return function combination(state = {}, action) {
  137. if (sanityError) {
  138. throw sanityError
  139. }
  140.  
  141. if (NODE_ENV !== 'production') {
  142. var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache)
  143. if (warningMessage) {
  144. warning(warningMessage)
  145. }
  146. }
  147.  
  148. var hasChanged = false
  149. var nextState = {}
  150. for (var i = 0; i < finalReducerKeys.length; i++) {
  151. var key = finalReducerKeys[i]
  152. var reducer = finalReducers[key]
  153. var previousStateForKey = state[key]
  154. var nextStateForKey = reducer(previousStateForKey, action)
  155. if (typeof nextStateForKey === 'undefined') {
  156. var errorMessage = getUndefinedStateErrorMessage(key, action)
  157. throw new Error(errorMessage)
  158. }
  159. nextState[key] = nextStateForKey
  160. hasChanged = hasChanged || nextStateForKey !== previousStateForKey
  161. }
  162. return hasChanged ? nextState : state
  163. }
  164. }

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. //排除所有中间件参数中不是function的
  21. funcs = funcs.filter(func => typeof func === 'function')
  22.  
  23. //如果只有一个中间件参数,就把这个唯一的中间件返回。
  24. if (funcs.length === 1) {
  25. return funcs[0]
  26. }
  27.  
  28. //如果中间件参数个数超过1个
  29.  
  30. //取出最后一个中间件参数
  31. const last = funcs[funcs.length - 1]
  32.  
  33. //将funcs中最开头到倒数第二个的数组复制一份,即排除了最后一个中间件
  34. const rest = funcs.slice(0, -1)
  35.  
  36. //返回(...args) => f(g(h(...args))).
  37. return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args))
  38. }

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

  1. 假如:compose(f, g, h)
  2. 分装后:(...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) {
  20.  
  21. //短短几行,很简单哟。
    //返回我们在creteStore里看到的enhancer
  1. return (createStore) => (reducer, preloadedState, enhancer) => {
  2. var store = createStore(reducer, preloadedState, enhancer)
  3. var dispatch = store.dispatch
  4. var chain = []
  5.  
  6. var middlewareAPI = {
  7. getState: store.getState,
  8. dispatch: (action) => dispatch(action)
  9. }
  10.  
  11. //将 当前store的getState和dispacth方法挂载到中间件里。
  12. chain = middlewares.map(middleware => middleware(middlewareAPI))
  13. dispatch = compose(...chain)(store.dispatch)
  14.  
  15. return {
  16. ...store,
  17. dispatch
  18. }
  19. }
  20. }

假如我们在代码里看到:

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

  1. 我们根据上面的代码走一遍,看看是怎么个执行过程。
  1. 1 applyMiddleware(promise, thunk, observable) 会返回enhancer.

  1. 2
    enhancer(createStore) 返回一个将中间件参数都闭包进来的 createStore函数,此时我们叫他加强版!我给他标注是红色;
  2. 3createStore(reducer) 然后就是上面代码的21-34行。 最后我们关心一下这个返回的store里的dispatch,其实是加强版的,因为里面是执行中间件的!!但是中间件里面到底干了什么,
    我们目前不得而知,总之记住,dispacth现在牛逼了就行。比如可以处理异步啦等等。
  1. 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天,这函数我自己都没用过····哈哈。不过以后肯定要用了!!!

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

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

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

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

    磨刀不误砍柴工,咱先把react-redux里的工具函数分析一下: 源码点这里  shallowEqual.js export default function shallowEqual(objA, ...

  2. 正式学习React (七) react-router 源码分析

    学习react已经有10来天了,对于react redux react-redux 的使用流程和原理,也已经有一定的了解,在我上一篇的实战项目里,我用到了react-route,其实对它还只是 停留在 ...

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

    parser模块是easyloader第一个加载的模块,它的主要作用,就是扫描页面上easyui开头的class标签,然后初始化成easyui控件. /** * parser模块主要是解析页面中eas ...

  4. EasyUI学习总结(四)——parser源码分析(转载)

    本文转载自:http://www.cnblogs.com/xdp-gacl/p/4082561.html parser模块是easyloader第一个加载的模块,它的主要作用,就是扫描页面上easyu ...

  5. Redux源码分析之applyMiddleware

    Redux源码分析之基本概念 Redux源码分析之createStore Redux源码分析之bindActionCreators Redux源码分析之combineReducers Redux源码分 ...

  6. Redux源码分析之createStore

    接着前面的,我们继续,打开createStore.js, 直接看最后, createStore返回的就是一个带着5个方法的对象. return { dispatch, subscribe, getSt ...

  7. Redux源码分析之基本概念

    Redux源码分析之基本概念 Redux源码分析之createStore Redux源码分析之bindActionCreators Redux源码分析之combineReducers Redux源码分 ...

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

    上一篇回顾:<memcached学习笔记——存储命令源码分析上篇>通过分析memcached的存储命令源码的过程,了解了memcached如何解析文本命令和mencached的内存管理机制 ...

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

    原创文章,转载请标明,谢谢. 上一篇分析过memcached的连接模型,了解memcached是如何高效处理客户端连接,这一篇分析memcached源码中的process_update_command ...

随机推荐

  1. 【转】node.exe调试JavaScript代码

    node.exe调试JavaScript代码 目的: Console.log可以打印一些信息,光有log还不够,当程序出现问题时通过log可以定位到错误位置,但是当我们想查看错误现场的变量时,log就 ...

  2. Lumen 队列

    队列 简介 连接 Vs. 队列 驱动的必要设置 创建任务类 生成任务类 任务类结构 分发任务 延迟分发 任务链 自定义队列 & 连接 指定任务最大尝试次数 / 超时值 频率限制 错误处理 运行 ...

  3. 为什么要使用自增ID作为主键

    1.从业务上来说 在设计数据库时不需要费尽心思去考虑设置哪个字段为主键.然后是这些字段只是理论上是唯一的,例如使用图书编号为主键,这个图书编号只是理论上来说是唯一的,但实践中可能会出现重复的 情况.所 ...

  4. AOSP5.0换8G eMMC不能开机问题

    AOSP5.0 MT6572平台.用H9TP32A4GDBCPR_KGM这颗4G的eMMC就能够.可是用H9TP65A8JDACPR_KGM这个8G的就开不了机,一直是重新启动.用串口抓LOG发现以下 ...

  5. mstsc远程登录设置

    mstsc终于可以连上了, 1.系统属性 远程允许, 2.开启三个服务: Remote Desktop ConfigurationRemote Desktop ServicesRemote Deskt ...

  6. Poj1482

    It's not a Bug, It's a Feature! Time Limit: 5000MS   Memory Limit: 30000K Total Submissions: 1428   ...

  7. iis express worker process已停止工作

    以管理员方式运行命令提示符工具,然后执行以下语句 netsh winsock reset 重启电脑

  8. 如何使用android studio及夜神模拟器开发调试

    android studio 只安装sdk(不安装自带模拟器)1.下载并安装夜神模拟器 2.先启动夜神模拟器 3.然后运行cmd命令,cd到夜神安装目录(bin目录下),执行命令: nox_adb.e ...

  9. 【转】windows 下 goprotobuf 的安装与使用

    1. 安装 在网上看了很多教程,都提到要安装 protoc 与 protoc-gen-go,但通过尝试之后并不能正确安装 protoc,一下记录能够顺利安装 protoc 与 protoc-gen-g ...

  10. transaction 数据库事务 roolback 回滚

    事务是恢复和并发控制的基本单位 https://baike.baidu.com/item/数据库事务/9744607 事务有三种模型: 1.隐式事务是指每一条数据操作语句都自动地成为一个事务,事务的开 ...