30 天精通 RxJS (03):Functional Programming 通用函式

发布时间 2023-08-04 17:29:05作者: 楚小九
RxJS Logo
了解 Functional Programming 的通用函式,能让我们写出更简洁的代码,也能帮助我们学习 RxJS。

读者可能会很好奇,我们的主题是 RxJS 为什么要特别讲 Functional Programming 的通用函式呢? 实际上,RxJS 核心的 Observable 操作观念跟 FP 的阵列操作是极为相近的,只学会以下几个基本的方法跟观念后,会让我们之后上手 Observable 简单很多!

今天的代码比较多,大家可以直接看影片!

ForEach

forEach 是 JavaScript 在 ES5 后,原生就有支持的方法。

原本我们可能要透过 for loop 取出阵列中的每一个元素

	var arr = ['Jerry', 'Anna'];
	for(var i = 0; i < arr.length; i++) {
		console.log(arr[i]);
	}

现在可以直接透过阵列的 forEach 取出每一个元素。

	var arr = ['Jerry', 'Anna'];
	arr.forEach(item => console.log(item));

forEach 是 FP 操作阵列的基本方法,我们可以用这个方法来实作下面三个我们今天要讲的重点分别为 map, filter, concatAll。

Map

试着把 newCourseList 每个元素的 { id, title } 塞到新的阵列 idAndTitlePairs

	var newCourseList = [
		{
			"id": 511021,
			"title": "React for Beginners",
			"coverPng": "https://res.cloudinary.com/dohtkyi84/image/upload/v1481226146/react-cover.png",
			"rating": 5
		},
		{
			"id": 511022,
			"title": "Vue2 for Beginners",
			"coverPng": "https://res.cloudinary.com/dohtkyi84/image/upload/v1481226146/react-cover.png",
			"rating": 5
		},
		{
			"id": 511023,
			"title": "Angular2 for Beginners",
			"coverPng": "https://res.cloudinary.com/dohtkyi84/image/upload/v1481226146/react-cover.png",
			"rating": 5
		},
		{
			"id": 511024,
			"title": "Webpack for Beginners",
			"coverPng": "https://res.cloudinary.com/dohtkyi84/image/upload/v1481226146/react-cover.png",
			"rating": 4
		}
	], idAndTitle = [];
	newCourseList.forEach((course) => {
		idAndTitle.push({ id: course.id, title: course.title });
	});

虽然我们成功的把 newCourseList 转成 idAndTitlePairs,但这样的写法还是显得有点太复杂了,我们可以用更抽象化的方式来完成。

上面我们练习到 newCourseList 转换成一个新的阵列 idAndTitlePairs,这个转换的过程其实就是两件事

  • 遍历 newCourseList 所有的元素
  • 把每个元素的预期值给到新的阵列

把这个过程抽象化成一个方法 map,以下是简化的基本思路:

  1. 我们会让每个阵列都有一个 map 方法
  2. 这个方法会让用户自定义传入一个 callback function
  3. 这个 callback function 会回传用户预期的元素

虽然 ES5 之后原生的 JavaScript 阵列有 map 方法了,但希望读者自我实做一次,能帮助理解。

	// 我们希望每一个阵列都有一个 map 这个方法,所以我们在 Array.prototype 扩充 map function
	Array.prototype.map = function(callback) {
	  var result = []; // map 最後一定會返回一個新陣列,所以我們先宣告一個新陣列

	  this.forEach(function(element, index) {
		  // this 就是呼叫 map 的阵列
		  result.push(callback(element, index));
		  // 执行使用者定义的 callback, callback 会回复使用者预期的元素,所以我们把它 push 这新阵列
	  })

	  return result;
	}

这里用到了 JavaScript 的 prototype chain 以及 this 等观念,可以看此影片了解 TODO!

到这里我们就实作完成 map 的方法了,让我们来试试这个方法吧!

	var idAndTitle = newCourseList
					 .map((course) => {
						 return { id: course.id, title: course.title };
					 });