关于一段ES6代码的探讨

2020/3/2 11:16:18

本文主要是介绍关于一段ES6代码的探讨,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

说在前面的话

疫情不出门,在家也无聊,打开浏览器翻看各个收藏夹,想找点好康的,突然发现了很久以前收藏的 30s一个代码片段,选择了JS语言,然后随机给我了一个代码片段www.30secondsofcode.org/js/s/pipe-a…,仔细一看,顿时惊到了,一行代码就写完了。。完全看不懂。。于是来了兴趣,便研究了起来。

这里展出这段代码:

const pipeAsyncFunctions =
      (...fns) => arg => fns.reduce((p, f) => p.then(f), Promise.resolve(arg));

// EXAMPLES
const sum = pipeAsyncFunctions(
  x => x + 1,
  x => new Promise(resolve => setTimeout(() => resolve(x + 2), 1000)),
  x => x + 3,
  async x => (await x) + 4
);
(async () => {
  console.log(await sum(5)); // 15 (after one second)
})();
复制代码

分析

根据下面示例显示,1秒后会输出15,试着将5代入 sum函数 的几个箭头函数中累加了一下,结果没错,也就是说pipeAsyncFunctions 函数能将传进去的几个箭头函数依次执行一遍。再看到 reduce 函数,可以确定 p,f 两个参数想必就是 sum 传入的几个函数。

reduce 函数可以将数组中的每一项依次执行指定的回调函数:

arr.reduce(callback,[initValue])
// 回调函数有四个参数
callback(preValue,currentValue,?index,?arr)
复制代码

改写代码

为了更好理解这段代码,我在 VS Code 中将这段代码改成了更适合理解的写法:

/* 
const pipeAsyncFunctions = 
	(...fns) => arg => fns.reduce((p, f) => p.then(f), Promise.resolve(arg));
*/
const pipeAsyncFunctions = function(...fns) {
  console.log("fns:", fns);
  // fns: [ [Function], [Function], [Function], [Function] ]
  return function(arg) {
    console.log("arg:", arg);
    // arg: 5
    return fns.reduce(function(p, f, index, arr) {
      return p.then(f);
    }, Promise.resolve(arg));
  };
};

const sum = pipeAsyncFunctions(
  x => x + 1,
  x => x + 2,
  x => x + 3,
  x => x + 4
);
(async () => {
  console.log(await sum(5)); // 15 (after one second)
})();

复制代码

这里的 fns 即为传入的四个函数通过 三点运算符 形成的数组,通过打印输出可以证实这一点,同时确定了 arg,p,f 的值。之所以 fns 不是 sum(5) 传入的5,是因为 sum函数 实际接收的是 pipeAsyncFunctions 返回的函数,即 function(arg) {...}

const sum = pipeAsyncFunctions(
  x => x + 1,
  x => x + 2,
  x => x + 3,
  x => x + 4
);
// 等效于

const temp = pipeAsyncFunctions(...fns) //temp接受执行后的返回值
const sum = temp;
/* 
  const sum  = function(arg) {
    return fns.reduce(function(p, f) {
      return p.then(f);
    }, Promise.resolve(arg));
  };
*/
复制代码

对于 reduce 函数的 initValue 值要写成 Promise.resolve(arg) ,个人认为是为了将 arg 变成 Promise 对象,从而在回调函数中使 p 使用 then 方法执行 fns 中的各函数得到结果。所以要在最后使用 ES7的 async和await 语法等待异步函数执行完成再输出最终结果。

结语

这段代码初一看显得有些难以理解,但是只需要将其进行拆分,转换成 ES5 的写法就会变得很容易理解了,最值得关注的便是 reducepromise 的使用技巧了。当然,这样难以理解的高(zhuang)级(bi)技巧,平时研究一下原理就好,团队合作的时候就不要写了。好麻烦啊



这篇关于关于一段ES6代码的探讨的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程