zoukankan      html  css  js  c++  java
  • JS

    背景

    最近需要改点 neo4j-browser 的代码做个 demo,分析初始化时运行命令的代码时花了很多时间,记录一下。

    目的

    找出 dispatch SINGLE_COMMAND_QUEUED action 的地方。

    PS: 要是会 redux-observable, Redux, RxJS 这哥三的话应该一下就能找到了。。

    分析

    首先通过读 neo4j-browser 的源码知道了发出命令都是通过:

    1. Redux dispatch action
    2. redux-observable 将 action 流入 RxJS
    3. RxJS 处理
    4. redux-observable 处理 RxJS 流出的 action(s)

    实现的。

    所以我们可以在SINGLE_COMMAND_QUEUEDmergeMap里截胡一下看看,发现调用栈只有两个地方有自己的代码(其余的都是 node_modules 中的)。

    • src/shared/modules/commands/commandsDuck.js:214
    export const handleSingleCommandEpic = (action$, store) =>
      action$
        .ofType(SINGLE_COMMAND_QUEUED)
        .merge(action$.ofType(SYSTEM_COMMAND_QUEUED))
        .map(action =>
          buildCommandObject(action, helper.interpret, getCmdChar(store.getState()))
        )
        .mergeMap(({ action, interpreted, cmdchar }) => {
          // 这里截胡
          /*
            调用栈:
            (anonymous) (commandsDuck.js:214)
            ...别人的代码
            ./src/browser/AppInit.jsx 
          */
          debugger;
          return new Promise((resolve, reject) => {
            const noop = { type: 'NOOP' }
            if (!(action.cmd || '').trim().length) {
              resolve(noop)
              return
            }
            if (interpreted.name !== 'cypher') {
              action.cmd = cleanCommand(action.cmd)
            }
            const res = interpreted.exec(action, cmdchar, store.dispatch, store)
            if (!res || !res.then) {
              resolve(noop)
            } else {
              res
                .then(r => {
                  store.dispatch(fetchMetaData())
                  resolve(noop)
                })
                .catch(e => resolve(noop))
            }
          })
        })
    

    可惜AppInit.js这里并没有直接 dispatch SINGLE_COMMAND_QUEUED 这个 action。

    • src/browser/AppInit.js:87
    // Signal app upstart (for epics)
    store.dispatch({ type: APP_START, url: window.location.href, env })
    

    继续找找发现在STARTUP_CONNECTION_SUCCESS这个 action dispatch 后会有一系列列操作,SINGLE_COMMAND_QUEUED 这个 action 在程序初始化时就作为 RxJS 的 mapTo 操作符的参数保存起来了,然后在STARTUP_CONNECTION_SUCCESS dispatch 后由 RxJS 流出,然后经过 redux-observable 进行 dispatch 的。这些操作都是通过调用 node_modules 中的函数(redux-observable、RxJS)完成的。

    • src/shared/modules/connections/connectionsDuck.js:398
    export const startupConnectionSuccessEpic = (action$, store) => {
      return action$
        .ofType(STARTUP_CONNECTION_SUCCESS)
        .do(() =>
          store.dispatch(
            executeSystemCommand(getCmdChar(store.getState()) + 'server status')
          )
        )
        .mapTo(
          // 这行在创建 epic 就执行了,创建出的 action 已经通过 redux-observable 保存在 rxjs 的 Subscribe 中。
          // 所以截胡的结果除了src/browser/AppInit.js:87,别的全是调用的 rxjs 等模块的函数
          executeSystemCommand(getInitCmd(store.getState()))
        ) // execute initCmd from settings
    }
    
  • 相关阅读:
    0001 工作业务问题_滞纳金公式计算区别实例
    001 win10下安装linux子系统--Ubuntu及其图形界面
    Java知识系统回顾整理01基础07类和对象01引用
    Java知识系统回顾整理01基础06数组07数组工具类Arrays
    Java知识系统回顾整理01基础06数组06二维数组
    Vue 框架中添加百度地图组件
    VUE中使用vue.nextTick 报this.nextTick is not a function错误
    VUE 饿了么项目实战 VUE "TypeError: Cannot read property 'deliveryPrice' of undefined"报错
    VUE vue2.0配置webpack.dev.conf.js加载本地json数据
    VUE response.json() 的更新问题
  • 原文地址:https://www.cnblogs.com/jffun-blog/p/12046210.html
Copyright © 2011-2022 走看看