# fed-e-task-01-01 **Repository Path**: lv_jing0359/fed-e-task-01-01 ## Basic Information - **Project Name**: fed-e-task-01-01 - **Description**: 拉勾大前端作业:Part1 - 模块一 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2020-06-17 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 简答题 ## 一、谈谈你是如何理解 JS 异步编程的,EventLoop、消息队列都是做什么的,什么是宏任务,什么是微任务? 答:JS 异步编程: 解决了单线程的 js 语言无法同时处理大量耗时任务的问题,不会等待这个任务的结束才开始执行下一个任务,对于耗时任务,都是开启过后就立即执行下一个任务,后续逻辑通过回调函数的方式定义,内部耗时任务完成后,会自动执行这个回调函数; EventLoop:即事件循环,负责监听调用栈和消息队列,一旦调用栈中的所有的任务都结束了,事件循环就会从消息队列中取出第一个回调函数,压入到调用栈,依次论推,直到所有任务执行完成 消息队列:即为待办的工作表,异步任务执行后会将这个任务的回调放入消息队列中排队,等待调用栈中的任务执行完成后依次放入调用栈中执行 宏任务:就是回调队列中的任务,一个新的宏任务会被加到队列末尾,依次排队执行 微任务:会在本次任务结束后直接执行,不需要再重新在队列中排队 # 代码题 ## 一、将下面异步代码使用 Promise 的方式改进 ```javascript setTimeout(function () { var a = 'hello'; setTimeout(function () { var b = 'lagou'; setTimeout(function () { var c = 'I Love U'; console.log(a + b + c); }, 10); }, 10); }, 10); ``` 答:./code/1.js ## 二、基于以下代码完成下面的四个练习 答:./code/2.js ```javascript const fp = require('lodash/fp'); // 数据 // horsepower 马力,dollar_value 价格,in_stock 库存 const cars = [ { name: 'Ferrari FF', horsepower: 660, dollar_value: 700000, in_stock: true }, { name: 'Spyker C12 Zagato', horsepower: 650, dollar_value: 648000, in_stock: false }, { name: 'Jaguar XKR-S', horsepower: 550, dollar_value: 132000, in_stock: false }, { name: 'Audi R8', horsepower: 525, dollar_value: 114200, in_stock: false }, { name: 'Aston Martin One-77', horsepower: 750, dollar_value: 1850000, in_stock: true }, { name: 'Pagani Huayra', horsepower: 700, dollar_value: 1300000, in_stock: false } ]; ``` ### 练习 1:使用函数组合 fp.flowRight() 重新实现下面这个函数 ```javascript let isLastInStock = function (cars) { // 获取最后一条数据 let last_car = fp.last(cars); // 获取最后一条数据的 in_stock 属性值 return fp.prop('in_stock', last_car); }; ``` ### 练习 2:使用 fp.flowRight()、fp.prop() 和 fp.first() 获取第一个 car 的 name ### 练习 3:使用帮助函数 \_average 重构 averageDollarValue,使用函数组合的方式实现 ```javascript let _average = function (xs) { return fp.reduce(fp.add, 0, xs) / xs.length; }; // <- 无需改动 let averageDollarValue = function (cars) { let dollar_values = fp.map(function (car) { return car.dollar_value; }, cars); return _average(dollar_values); }; ``` ### 练习 4:使用 flowRight 写一个 sanitizeNames() 函数,返回一个下划线连接的小写字符串,把数组中的 name 转换为这种形式:例如:sanitizeNames(["Hello World"]) => ["hello_world"] ```javascript let _underscore = fp.replace(/\W+/g, '_'); // 无需改动,并在 sanitizeNames 中使用它 ``` ## 三、基于下面提供的代码,完成后续的四个练习 答:./code/3.js ```javascript // support.js class Container { static of(value) { return new Container(value); } constructor(value) { this._value = value; } map(fn) { return Container.of(fn(this._value)); } } class MayBe { static of(x) { return new MayBe(x); } isNothing() { return this._value === null || this._value === undefined; } constructor(x) { this._value = x; } map(fn) { return this.isNothing() ? this : MayBe.of(fn(this._value)); } } module.exports = { MayBe, Container }; ``` ### 练习 1:使用 fp.add(x,y) 和 fp.map(f,x) 创建一个能让 functor 里的值增加的函数 ex1 ```javascript // app.js const fp = require('lodash/fp'); const { MayBe, Container } = require('./support'); let MayBe = MayBe.of([5, 6, 1]); let ex1 = () => { // 你需要实现的函数。。。 }; ``` ### 练习 2:实现一个函数 ex2,能够使用 fp.first 获取列表的第一个元素 ```javascript // app.js const fp = require('lodash/fp'); const { MayBe, Container } = require('./support'); let xs = Container.of(['do', 'ray', 'me', 'fa', 'so', 'la', 'ti', 'do']); let ex2 = () => { // 你需要实现的函数。。。 }; ``` ### 练习 3:实现一个函数 ex3,使用 safeProp 和 fp.first 找到 user 的名字的首字母 ```javascript const fp = require('lodash/fp'); const { MayBe, Container } = require('./support'); let safeProp = fp.curry(function (x, o) { return MayBe.of(o(x)); }); let user = { id: 2, name: 'Albert' }; let ex3 = () => { // 你需要实现的函数。。。 }; ``` ### 练习 4:使用 MayBe 重写 ex4,不要有 if 语句 ```javascript const fp = require('lodash/fp'); const { MayBe, Container } = require('./support'); let ex4 = function (n) { if (n) { return parseInt(n); } }; ``` ## 四、手写实现 MyPromise 源码 要求:尽可能还原 Promise 中的每一个 API,并通过注释的方式描述思路和原理。 答:./code/4.js