redux的createStore的源碼,注釋已經(jīng)翻譯成中文,至于代碼,你們應(yīng)該看得懂

如果看不清楚,可以查看https://segmentfault.com/a/1190000018385942

import isPlainObject from 'lodash/isPlainObject'

import $$observable from 'symbol-observable'

/**

* These are private action types reserved by Redux.

* For any unknown actions, you must return the current state.

* If the current state is undefined, you must return the initial state.

* Do not reference these action types directly in your code.

*

* 這些都是redux本身預(yù)置的私有action types

* 對(duì)于任何未知的action, 你一定要return當(dāng)前的state.

* 如果當(dāng)前的state是undefined, 你一定要return最初始的state.

* 一定,一定,一定不要在代碼中直接引用action types .

*/

export const ActionTypes = {? //初始化action的type,沒(méi)有action參數(shù)的時(shí)候用

? ? ? ?INIT: '@@redux/INIT'

}

/**

* Creates a Redux store that holds the state tree.

* The only way to change the data in the store is to call `dispatch()` on it.

* There should only be a single store in your app. To specify how different

* parts of the state tree respond to actions, you may combine several reducers

* into a single reducer function by using `combineReducers`.

*

* 創(chuàng)建一個(gè)包含state tree(狀態(tài)樹(shù))的redux store.

* 唯一改變store中data(數(shù)據(jù))的方法是調(diào)用`dispatch()`方法.

* 在你的程序中應(yīng)該只存在唯一一個(gè)store, 來(lái)表明state tree各部分怎樣對(duì)action做出反應(yīng)

* 你可能需要將多個(gè)reducer用`combineReducers`組合在一起

*

* @param {Function} reducer A function that returns the next state tree, given

* the current state tree and the action to handle.

*

* @param {Function} reducer 參數(shù)reducer是一個(gè)返回下一個(gè)state tree(狀態(tài)樹(shù))的函數(shù),來(lái)操作當(dāng)前的state和action

*

* @param {any} [preloadedState] The initial state. You may optionally specify it

* to hydrate the state from the server in universal apps, or to restore a

* previously serialized user session.

* If you use `combineReducers` to produce the root reducer function, this must be

* an object with the same shape as `combineReducers` keys.

*

* @param {any} [preloadedState] 初始化的state,可選參數(shù),你可以在universal(一般的,普遍的,我不知道怎么說(shuō)比較合適)

* 的程序中與服務(wù)器的state結(jié)合,或者restore一個(gè)預(yù)先連續(xù)的user session(直譯過(guò)來(lái)的,一般用不到)

* 如果你用`combineReducers`產(chǎn)生一個(gè)根reducer函數(shù),這一定是一個(gè)和`combineReducers`的key一樣的對(duì)象(根reducer是一個(gè)對(duì)象)

*

* @param {Function} [enhancer] The store enhancer. You may optionally specify it

* to enhance the store with third-party capabilities such as middleware,

* time travel, persistence, etc. The only store enhancer that ships with Redux

* is `applyMiddleware()`.

*

* @param {Function} [enhancer] store增強(qiáng)器. 可選參數(shù).用來(lái)增強(qiáng)第三方庫(kù)的能力集(這個(gè)詞是直譯),

* 比如中間件,時(shí)空穿越,和持續(xù)性(也是直譯).redux的store增強(qiáng)器是`applyMiddleware()`

*

* @returns {Store} A Redux store that lets you read the state, dispatch actions

* and subscribe to changes.

*

* @returns {Store} 返回值 一個(gè)redux的store,讓你可以讀取state, dispatch actions 和訂閱更改

*/

//createStore的目的只是創(chuàng)建一個(gè)store,這個(gè)store包含5個(gè)方法(一般只用到3個(gè),最常用的是dispatch)

export default function createStore(reducer, preloadedState, enhancer) {

? if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {

? ? enhancer = preloadedState

? ? preloadedState = undefined

? }

? if (typeof enhancer !== 'undefined') {

? ? if (typeof enhancer !== 'function') {

? ? ? throw new Error('Expected the enhancer to be a function.')//期望enhancer是個(gè)函數(shù)

? ? }

? ? // 當(dāng)enhancer是函數(shù)的時(shí)候返回,然后執(zhí)行,并將createStore作為參數(shù)傳入,然后createStore就在? ? ? ? ?//enhancer里面去執(zhí)行了

? ? return enhancer(createStore)(reducer, preloadedState)

? }

? if (typeof reducer !== 'function') {

? ? throw new Error('Expected the reducer to be a function.')

? }

? let currentReducer = reducer? //一般此reducer不是單個(gè)的reducer函數(shù),而是combineReducers函數(shù)

? let currentState = preloadedState

? let currentListeners = []? //監(jiān)聽(tīng)函數(shù)

? let nextListeners = currentListeners

? let isDispatching = false

? function ensureCanMutateNextListeners() { //nextListeners不是currentListeners

? ? if (nextListeners === currentListeners) {

? ? ? nextListeners = currentListeners.slice()

? ? }

? }

? /**

? * Reads the state tree managed by the store.

? *

? * 讀取被store管理的state樹(shù)

? *

? * @returns {any} The current state tree of your application.

? *

? *返回你的程序的當(dāng)前的state樹(shù)

? */

? function getState() {

? ? ? ?return currentState

? }

? /**

? * Adds a change listener. It will be called any time an action is dispatched,

? * and some part of the state tree may potentially have changed. You may then

? * call `getState()` to read the current state tree inside the callback.

? *

? * 添加一個(gè)改變事件,任何時(shí)候一個(gè)action被dispatch這個(gè)事件就會(huì)被調(diào)用,然后state樹(shù)的某一部分就

? * 會(huì)改變. 你也可以在回調(diào)函數(shù)里面調(diào)用`getState()`來(lái)查看當(dāng)前的state樹(shù)

? *

? * You may call `dispatch()` from a change listener, with the following

? * caveats:

? *

? * 以下幾種情況你也可以調(diào)用`dispatch()`

? *

? * 1. The subscriptions are snapshotted just before every `dispatch()` call.

? * If you subscribe or unsubscribe while the listeners are being invoked, this

? * will not have any effect on the `dispatch()` that is currently in progress.

? * However, the next `dispatch()` call, whether nested or not, will use a more

? * recent snapshot of the subscription list.

? *

? * 每次調(diào)用`dispatch`之前,訂閱都會(huì)被snapshot,

? * 當(dāng)事件被觸發(fā)的時(shí)候你訂閱或者不訂閱,在當(dāng)前的進(jìn)程中都不會(huì)對(duì)`dispatch`有什么影響

? * 然而當(dāng)下一次`dispatch`被調(diào)用時(shí),無(wú)論嵌套與否,將會(huì)使用最近的訂閱列表的snapshot

? *

? * 2. The listener should not expect to see all state changes, as the state

? * might have been updated multiple times during a nested `dispatch()` before

? * the listener is called. It is, however, guaranteed that all subscribers

? * registered before the `dispatch()` started will be called with the latest

? * state by the time it exits.

? *

? * 不要期待監(jiān)聽(tīng)事件可以看到所有的狀態(tài)改變,因?yàn)樵谑录徽{(diào)用前,state在嵌套的`dispatch`間

? * 可能已經(jīng)更新了很多次

? *

? * @param {Function} listener A callback to be invoked on every dispatch.

? * 每次dispatch都會(huì)被出發(fā)的回調(diào)函數(shù)

? *

? * @returns {Function} A function to remove this change listener.

? * 返回一個(gè)移除該事件的函數(shù)

? */

? function subscribe(listener) {

? ? ? ?if (typeof listener !== 'function') {

? ? ? ? ? ? ? throw new Error('Expected listener to be a function.')

? ? ? ? }

? ? ? ? let isSubscribed = true

? ? ? ? ensureCanMutateNextListeners()

? ? ? ? ?nextListeners.push(listener) //添加事件到nextListeners數(shù)組

? ? ? ? ?return function unsubscribe() {

? ? ? ? ? ? ? ? if (!isSubscribed) {

? ? ? ? ? ? ? ? ? ? ? ? return

? ? ? ? ? ? ? ? ?}

? ? ?? ? ? isSubscribed = false

? ? ? ? ? ? ensureCanMutateNextListeners()

? ? ? ? ? ? const index = nextListeners.indexOf(listener)

? ? ? ? ? ? ?nextListeners.splice(index, 1) //從nextListeners數(shù)組中移除事件

? ? ? ? ?}

? ? ? ?}

? /**

? * Dispatches an action. It is the only way to trigger a state change.

? *

? * dispatch? action是唯一觸發(fā)state改變的途徑

? *

? * The `reducer` function, used to create the store, will be called with the

? * current state tree and the given `action`. Its return value will

? * be considered the **next** state of the tree, and the change listeners

? * will be notified.

? *

? * `reducer`函數(shù),被用來(lái)創(chuàng)建store,有當(dāng)前的state樹(shù)和action就會(huì)被調(diào)用(state和action是reducer函數(shù)的參數(shù))

? * 它的返回值會(huì)被當(dāng)做下一個(gè)state樹(shù).監(jiān)聽(tīng)事件會(huì)注意到state樹(shù)的改變

? *

? * The base implementation only supports plain object actions. If you want to

? * dispatch a Promise, an Observable, a thunk, or something else, you need to

? * wrap your store creating function into the corresponding middleware. For

? * example, see the documentation for the `redux-thunk` package. Even the

? * middleware will eventually dispatch plain object actions using this method.

? *

? * 最基本的用法是僅支持 為純對(duì)象的 action,如果你想要dispatch一個(gè)promise,一個(gè)Observable,

? * thunk,或是其他東西,你需要封裝store創(chuàng)建一個(gè)進(jìn)入到相應(yīng)中間件的函數(shù).? 比如,看一個(gè)`redux-thunk`

? * 的文檔,即使是中間件最終也會(huì)用這個(gè)方法dispatch? 純對(duì)象的action

? *

? * @param {Object} action A plain object representing “what changed”. It is

? * a good idea to keep actions serializable so you can record and replay user

? * sessions, or use the time travelling `redux-devtools`. An action must have

? * a `type` property which may not be `undefined`. It is a good idea to use

? * string constants for action types.

? *

? * action是一個(gè)純對(duì)象,代表'什么被改變了'. 保持action的連續(xù)性是個(gè)好主意,這樣你就可以記錄和

? * 重現(xiàn)user session,或者使用時(shí)空穿梭`redux-devtools`.

? * action必須包含一個(gè)`type`屬性,即使是`undefined`. 通常使用字符串常量表示

? *

? * @returns {Object} For convenience, the same action object you dispatched.

? *

? * 為了方便,返回你dispatch的action

? *

? * Note that, if you use a custom middleware, it may wrap `dispatch()` to

? * return something else (for example, a Promise you can await).

? * 注意 如果你想使用特定的中間件,可封裝`dispatch`返回其他東西(比如, 一個(gè)異步調(diào)用的promise)

? *

? */

? function dispatch(action) {

? ? if (!isPlainObject(action)) {

? ? ? throw new Error(

? ? ? ? 'Actions must be plain objects. ' +

? ? ? ? 'Use custom middleware for async actions.'

? ? ? )? ?//actions必須為純對(duì)象,使用特定中間件異步調(diào)用actions

? ? }

? ? if (typeof action.type === 'undefined') {

? ? ? throw new Error(

? ? ? ? 'Actions may not have an undefined "type" property. ' +

? ? ? ? 'Have you misspelled a constant?'

? ? ? )??//actions可能有一個(gè)未定義的type屬性,你可能拼錯(cuò)了這個(gè)常量

? ? }

? ? if (isDispatching) {

? ? ? throw new Error('Reducers may not dispatch actions.')//reducer沒(méi)有dispatch action

? ? }

? ? try {

? ? ? isDispatching = true

? ? ? //dispatch的目的就是改變currentState

? ? ? currentState = currentReducer(currentState, action) //currentReducer = reducer

? ? } finally {

? ? ? isDispatching = false

? ? }

? ? const listeners = currentListeners = nextListeners? //訂閱函數(shù)的事件

? ? for (let i = 0; i < listeners.length; i++) {

? ? ? const listener = listeners[i]

? ? ? listener()

? ? }

? ? return action

? }

? /**

? * Replaces the reducer currently used by the store to calculate the state.

? *

? * 替換 store 當(dāng)前用來(lái)計(jì)算 state 的 reducer。

? *

? * You might need this if your app implements code splitting and you want to

? * load some of the reducers dynamically. You might also need this if you

? * implement a hot reloading mechanism for Redux.

? *

? * 這是一個(gè)高級(jí) API。只有在你需要實(shí)現(xiàn)代碼分隔,而且需要立即加載一些 reducer 的時(shí)候才可能會(huì)用到它。

? *在實(shí)現(xiàn) Redux 熱加載機(jī)制的時(shí)候也可能會(huì)用到

? *

? * @param {Function} nextReducer The reducer for the store to use instead.

? * store所替換的reducer

? * @returns {void}

? */

? function replaceReducer(nextReducer) {

? ? if (typeof nextReducer !== 'function') {

? ? ? throw new Error('Expected the nextReducer to be a function.')

? ? }

? ? currentReducer = nextReducer

? ? dispatch({ type: ActionTypes.INIT })

? }

? /**

? * Interoperability point for observable/reactive libraries.

? * @returns {observable} A minimal observable of state changes.

? * For more information, see the observable proposal:

? * https://github.com/tc39/proposal-observable

? *

? * observable/reactive庫(kù)的互用性

? * observable是一個(gè)mini的 可觀察state的改變

? * 在下面這個(gè)網(wǎng)址查看更多observable的信息

? */

? function observable() {

? ? const outerSubscribe = subscribe

? ? return {

? ? ? /**

? ? ? * The minimal observable subscription method.

? ? ? * @param {Object} observer Any object that can be used as an observer.

? ? ? * The observer object should have a `next` method.

? ? ? * @returns {subscription} An object with an `unsubscribe` method that can

? ? ? * be used to unsubscribe the observable from the store, and prevent further

? ? ? * emission of values from the observable.

? ? ? *

? ? ? * mini的可觀察訂閱的方法

? ? ? * observer是 任何對(duì)象都可以用作觀察者,這個(gè)觀察者應(yīng)該有一個(gè)`next`方法

? ? ? * subscription 一個(gè)有`unsubscribe`方法的對(duì)象.可以用做退訂observable,防止進(jìn)一步發(fā)出value值

? ? ? * (我也不知道什么意思,外國(guó)人說(shuō)話比較隨意)

? ? ? */

? ? ? subscribe(observer) {

? ? ? ? if (typeof observer !== 'object') {

? ? ? ? ? throw new TypeError('Expected the observer to be an object.')

? ? ? ? }

? ? ? ? function observeState() {

? ? ? ? ? if (observer.next) {

? ? ? ? ? ? observer.next(getState())

? ? ? ? ? }

? ? ? ? }

? ? ? ? observeState()

? ? ? ? const unsubscribe = outerSubscribe(observeState)

? ? ? ? return { unsubscribe }

? ? ? },

? ? ? [$$observable]() {

? ? ? ? return this

? ? ? }

? ? }

? }

? // When a store is created, an "INIT" action is dispatched so that every

? // reducer returns their initial state. This effectively populates

? // the initial state tree.

? /**

? * 當(dāng)創(chuàng)建一個(gè)store的時(shí)候,一個(gè)初始的action就被dispatch了,所以每個(gè)reducer都會(huì)返回初始的state

? * 這個(gè)可以很高效的得到state樹(shù)

? */

? dispatch({ type: ActionTypes.INIT })

? return {

? ? dispatch,

? ? subscribe,

? ? getState,

? ? replaceReducer,

? ? [$$observable]: observable

? }

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容