关于递归的一个问题

函数是这样的

const handleAddInfo = () => {
    // 添加的时候应该设置一个区别于在原有数据上编辑功能的标志
    this.props
      .dispatch({
        type: 'video/setAlarmRuleEditMode',
        payload: alarmRuleEditMode.add,
      })
      .then(() => {
        this.props.dispatch({
          type: 'video/setBlackListData',
          payload: {
            key: null,
          },
        });
      })
      .then(() => {
        this.props.dispatch({
          type: 'video/setNaviKey',
          payload: {
            key: 'addBlackList',
          },
        });
      });
  };

我想把它写成动态的,忘里面传几个参数就自动跟几个.then,感觉要用到递归的思路,但是自己递归的思想比较弱...不知道下面怎么去写了。请高手帮忙提示一些,感激不尽啦~

    function fn(...arg) {
        arg.forEach(...)
    }
阅读 1.3k
2 个回答

一次性传入任意数量参数

const handleAddInfo = (...args) => {
  return args.reduce((promise, opt) => {
    return promise.then(() => this.props.dispatch(opt))
  }, Promise.resolve())
}
handleAddInfo(
  {
    type: 'video/setAlarmRuleEditMode',
    payload: alarmRuleEditMode.add,
  },
  {
    type: 'video/setBlackListData',
    payload: {
      key: null,
    },
  },
  {
    type: 'video/setNaviKey',
    payload: {
      key: 'addBlackList',
    },
  },
)

把参数提出来

const handleAddInfo = opt => this.props.dispatch(opt)

handleAddInfo({
  type: 'video/setAlarmRuleEditMode',
  payload: alarmRuleEditMode.add,
})
  .then(() =>
    handleAddInfo({
      type: 'video/setBlackListData',
      payload: {
        key: null,
      },
    }),
  )
  .then(() =>
    handleAddInfo({
      type: 'video/setNaviKey',
      payload: {
        key: 'addBlackList',
      },
    }),
  )
// 或者
;[
  ({
    type: 'video/setAlarmRuleEditMode',
    payload: alarmRuleEditMode.add,
  },
  {
    type: 'video/setBlackListData',
    payload: {
      key: null,
    },
  },
  {
    type: 'video/setNaviKey',
    payload: {
      key: 'addBlackList',
    },
  }),
].reduce(
  (promise, opt) => promise.then(() => handleAddInfo(opt)),
  Promise.resolve(),
)

楼上使用了reduce可以返回promise串行执行的特性,厉害。
我提供一个递归的版本,比较朴素:

function serial (...args) {
  function runTask () {
    const arg = args.shift()
    return this.props.dispatch(arg).then(() => {
      if (args.length > 0) {
        return runTask()
      }
    })
  }
  return runTask()
}

serial(
  {
    type: 'video/setAlarmRuleEditMode',
    payload: alarmRuleEditMode.add,
  },
  {
    type: 'video/setBlackListData',
    payload: {
      key: null,
    },
  },
  {
    type: 'video/setNaviKey',
    payload: {
      key: 'addBlackList',
    },
  }
).then(() => {
    console.log('done')
})
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题