系统学习大前端(3)---函数式编程、异步编程练习

文章内容输出来源:拉勾教育大前端高薪训练营

一、简答

1、谈谈你是如何理解JS异步编程的,EventLoop、消息队列都是做什么的?什么是宏任务、什么是微任务?
由于JS是单线程的,这样执行任务会发生线程阻塞。所有JS引入了异步编程,通过回调的方式来解决这种阻塞。
对于像定时器这种异步任务以及IO任务、其它线程发送过来的任务,JS会将其放到消息队列中,通过EventLoop的机制从消息队列里面依次取出任务执行。
消息队列里的任务就是宏任务,微任务是promise、mutationObserver、nextTick。每一个宏任务都会配置一个微任务队列,微任务队列的执行时机是当前宏任务执行完毕、主线程退出之前。

二、编程题

1、将下面异步代码改成promise的方式实现

setTimeout(()=>{
    var a = 'hello ';
    setTimeout(()=>{
        var b = 'lagou '
        setTimeout(()=>{
            var c = 'i love u'
            console.log(a+b+c);
        },10)
    },10)
},10)

改造后:

var promise = new Promise((resolve,reject)=>{
    resolve('hello ')
}).then(res=>{
    return res + 'lagou '
}).then(res=>{
    return res + 'i love u'
}).then(res=>{
    console.log(res);
})

2、基于以下代码完成下面4个练习

const fp = require('lodash/fp')
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
    }
]

2.1 使用函数组合fp.flowRight()重新实现下面函数

let isLastInStock = function(cars){
    let last_car = fp.last(cars)
    return fp.prop('in_stock',last_car)
}
//实现
const fn = fp.flowRight(fp.prop('in_stock'),fp.last);

2.2 使用fp.flowRight() fp.prop() fp.first()获取第一个car的name

// 实现
const fn = fp.flowRight(fp.prop('name'),fp.first)

2.3 使用帮助函数_average重构averageDollarValue,使用函数组合的方式实现

let _average = function(xs){
    return fp.reduce(fp.add,0,xs)/xs.length
}
let averageDollarValue = function(cars){
    let dollar_values = fp.map((cars)=>{
        return cars.dollar_value
    },cars)
    return _average(dollar_values)
}

实现

const total = cars=>fp.map(cars=>cars.dollar_value,cars)
const fn = fp.flowRight(_average,total);
console.log(fn(cars));

2.4 使用flowRight写一个sanitizeNames()函数,返回一个下划线连接的小写字符串,把数组中的name转换成这种形式。

let _underscore = fp.replace(/\W+/g,'_');
const sanitizeNames = fp.flowRight(fp.map(_underscore),fp.map(fp.toLower),fp.map(car=>car.name))
console.log(sanitizeNames(cars));

3、基于下面提供的代码,完成以下四个练习

class Container {
    static of(val) {
        return new Container(val)
    }
    constructor(val) {
        this._val = val
    }
    map(fn) {
        return Container.of(fn(this._val))
    }
}

class Maybe {
    static of(x) {
        return new Maybe(x)
    }
    isNothing() {
        return this._val === null || this._val === undefined
    }
    constructor(x) {
        this._val = x
    }
    map(fn) {
        return this.isNothing() ? this : Maybe.of(fn(this._val))
    }
}
module.exports = {Maybe ,Container }

3.1 使用fp.add(x,y) fp.map(f,x)创建一个能让functor里的值增加的函数exl

let maybe = Maybe.of([5, 6, 1])
let exl = (x) => {
    return maybe.map(fp.map(a => fp.add(a, x)))
}
console.log(exl(2));

3.2 实现一个函数ex2 ,能使用fp.first获取列表的第一个元素

let xs = Container.of(['do','ray','me','fa','so','la','ti','do'])
let ex2 = ()=>{
    return xs.map(fp.first)
    //.map(item=>console.log(item))
}

3.3 实现一个函数ex3,使用safeProp和fp.first找到user的名字的首字母。

let safeProp = fp.curry((x,o)=>Maybe.of(o[x]))
let user = {id:2,name:'Albert'}
let ex3 = ()=>{
    let safe = safeProp('name',user)
    let names = safe.map(name=>name.split('')).map(fp.first)
    return names
}
console.log(ex3());

3.4 使用Maybe重写ex4 不要有if语句

// let ex4 = (n)=>{
//     if(n){
//         return parseInt(n)
//     }
// }

let ex4 = (n)=>{
  return Maybe.of(n).map(parseInt)
}

console.log(ex4(3.5));

4、 手写promise实现
参照-系统学习大前端(2)—手写promise

答案仅供参考,如有错误,欢迎指正。

你可能感兴趣的:(笔记)