如何实现支持任意数量回调的链式处理并传递回调结果?
如何实现支持任意数量回调的链式处理并传递回调结果?
看起来你现在遇到了两个核心问题:一是没法灵活处理任意数量的回调函数,二是现有代码里的变量作用域和条件判断逻辑导致了报错。咱们一步步来解决:
先说说你当前代码的问题
- 固定参数限制了回调数量:你把回调写成了
cb1, cb2, cb3这种固定参数,没法处理3个以上的回调,也不够灵活。 - 变量作用域错误:比如
res1只在第一个if块里定义,后面的else if块里根本访问不到它,再加上当只传一个回调时cb2是undefined,自然会报cb2(res1) is not a function的错误。 - 条件判断冗余且不通用:靠判断
cb2、cb3是否存在来处理逻辑,不仅容易出错,也没法扩展到更多回调的场景。
最优解决方案:用扩展运算符+reduce方法
没错,你一开始想到的**扩展运算符(spread operator)**就是解决任意数量参数的关键,再结合数组的reduce方法,完美适配这种“链式传递结果”的需求。
修改后的代码如下:
// 用...callbacks收集所有回调到数组里 let chainMap = function(num, ...callbacks) { // reduce遍历回调数组,把上一步结果传给下一个回调 return callbacks.reduce((currentVal, cb) => { return cb(currentVal); }, num); // 初始值是传入的num }; // 你的回调函数保持不变 let add5 = function(n) { return n + 5; }; let half = function(n) { return n / 2; }; let square = function(n) { return n * n; }; // 测试所有用例,结果都符合预期 console.log(chainMap(25, add5)); // 30 console.log(chainMap(25, add5, half)); // 15 console.log(chainMap(25, add5, half, square)); // 225 console.log(chainMap(4, square, half)); // 8 console.log(chainMap(4, half, square)); // 4
代码解释
...callbacks:会把除了第一个参数num之外的所有参数,不管数量多少,都收集成一个数组,彻底解决了任意数量回调的问题。reduce方法:这是处理链式传递的绝佳工具——它会从初始值num开始,依次把当前结果传给下一个回调函数,最终返回最后一次处理的结果。就算你不传任何回调,它也会直接返回初始值num,逻辑非常严谨。
为什么原来的代码会报错?
举个例子,当你调用chainMap(25, add5)时,cb2和cb3都是undefined,你的代码会进入第一个if块,定义res1并返回。但如果你的代码逻辑出现偏差(比如不小心进入else if块),就会出现两个问题:一是res1在这个块里未定义,二是cb2是undefined,调用cb2(res1)自然会报“不是函数”的错误。而用reduce的方式完全规避了这些条件判断的坑。
备注:内容来源于stack exchange,提问作者Julius Evans
相关产品推荐
相关产品推荐

