1 Star 0 Fork 0

不二 / 大前端学习

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

简答题

一、谈谈你是如何理解JS异步编程的,EventLoop、消息队列都是做什么的,什么是宏任务,什么是微任务?

(1)js异步编程

  • js的执行环境是单线程,只能在同一时间做一件事情,这样在进行大量耗时运算时将会阻塞代码执行,造成程序假死,所有需要用到异步编程来解决这种问题
  • 可以通过回调函数方式来做到异步编程,回调函数把需要执行的函数放到任务队列中,不占用主线程,当主线程执行完毕之后,才会将任务从任务队列进入到主线程执行

(2)event loop

  1. 同步任务在主线程执行,形成一个执行栈

  2. 在主线程之外,还存在一个任务队列,通过回调函数的形式将所要执行的函数放到任务队列中,不占用主线程

  3. 等主线程执行完毕后,系统会读取"任务队列",从而将任务从任务队列进入到主线程中执行。

  4. 主线程循环执行第三步

这个过程是不断循环的,所以整个运行机制被称为event loop

(3)消息队列

栈、堆、消息队列是一种数据结构,队列,特点为先进先出,存放执行的任务

(4)宏任务和微任务

  • 宏任务:消息队列中的每个任务都是宏任务,每次宏任务执行完毕之后查看相应的微任务队列是否为空,如果不为空,则会按照先进先出的规则全部执行完对应的微任务,如此循环,直至任务结束。

  • 微任务:每个宏任务对应都有一个微任务队列,微任务主要解决任务优先级的问题和单个任务执行过长的问题a

代码题

一、将下面异步代码使用 Promise的方式改进

setTimeout(function(){
    var a = "hellow";
    setTimeout(function(){
        var b = "lagou";
        setTimeout(function(){
            var c = "I ❤ U";
            // console.log(a + b +c);
        })
    })
});
	function timeOut (text){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve(text);
        },10);
    })
}

timeOut("hellow").then(res => {
    return timeOut(res + "lagou");
}).then(res=>{
    return timeOut(res + "I ❤ U");
}).then(res => {
    console.log(res);
});

二、基于以下代码完成下面四个练习

	const fp = require("lodash/fp");
/** 
 * 数据
 * horspower 马力
 * 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() 重新实现下面这个函数

let isLastInStock = function (cars) { 
    //获取最后一条数据 
    let last_car = fp.last(cars);
    //获取最后一条数据的 in_stock 属性值 
    return fp.prop('in_stock', last_car);
}

console.log(isLastInStock(cars));

let newLast = fp.flowRight(fp.prop("in_stock"),fp.last);

console.log(newLast(cars));

练习2:使用fp.flowRight()、fp.prop()和fp.first 获取第一个car的name

	let getFirstCarName = fp.flowRight(fp.prop("name"),fp.first);
console.log(getFirstCarName(cars));

练习3: 使用帮助函数_average重构 averageDollarValue,使用函数组合方式实现

let _average = function (xs) { 
    return fp.reduce(fp.add, 0, xs) / xs.length;
} // <‐ 无须改动

let averageDollarValue = function(array){
     let saveItem =  function (arr){
        let count = fp.map(function (car) { 
            return car.dollar_value
        }, arr);

        return count;
    }

    return fp.flowRight(_average,saveItem)(array);
};

let getAverage = averageDollarValue(cars);

console.log(getAverage);

练习4:使用flowRight 写一个sanitizeNames() 函数,返回一个下划线链接的小写字符串,把数组中的name转换为这种形式: 例如 写一个sanitizeNames(["Hello World"]) => ['hellow world']

	let _underscore = fp.replace(/\W+/g,"_");//无需改动并在函数中使用她

function sanitizeNames(array){
    return fp.flowRight(fp.map(_underscore),fp.map(fp.toLower))(array);
}

console.log(sanitizeNames(['Hello World',"DLFJADLFJDLSFSFJ","DFSFDSFDF"]));

三、基于下面提供的代码完成后续的四个练习

const { Maybe, Container } = require("./support.js");

练习1: 使用fp.add(x,y) 和 fp.map(f,x) 创建一个能让functor里的值增加的函数 ex1

	let maybe = Maybe.of([5, 6, 1]);
let ex1 = (num) => {  
    //你需要实现的函数...
    let fn = fp.flowRight(fp.map(fp.add(num)));
    return maybe.map(fn);
}
console.log(ex1(1));

练习2: 实现一个函数ex2 能够使用fp.first获取列表的第一个元素

	let xs = Container.of([
    "do",
    "ray",
    "me",
    "fa",
    "so",
    "la",
    "ti",
    "do"
])
let ex2 = () => {
    return xs.map(fp.first)._value
}

console.log(ex2());

练习3: 实现一个函数ex3 使用safeProp 和 fp.first 找到user 的名字首字目

	let safeProp = fp.curry(function (x, o) {
    return Maybe.of(o[x])
})
let user = { id: 2, name: 'Albert' }

let ex3 = () => {
    //你需要实现的函数...
    return  safeProp("name")(user).map(fp.first)._value;
}
console.log(ex3());

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

	let ex4 = function (n){
    if(n){
        return parseInt(n);
    }
}

let myEx4 = function(n){
    return Maybe.of(n).map(parseInt)._value;
}

console.log(myEx4(4645.12313));

手写实现MyPromise源码

  • 要求: 尽可能还原Promise中的每一个API, 并通过注释的方式描述思路和原理
const PENDING = "pending"; //等待
const PULFILLED = "pulfilled"; //成功
const REJECTED = "rejected";//失败

class myPromise{
    constructor(executr){
        try{
            executr(this.resolve,this.reject);
        }
        catch(err){
            this.reject(err);
        }
    }
    //成功之后的值
    value = undefined;
    //失败之后的原因
    reason = undefined;
    // Promise状态
    status = PENDING;
    //成功回调
    successCallback = [];
    //失败回调
    failCallback = [];
    //修改成功状态
    resolve = value =>{
        //如果状态不是等待直接退出函数
        if(this.status !== PENDING) return;
        this.status = PULFILLED;
        //设置成功后的值
        this.value = value;

        //this.successCallback && this.successCallback(value);
        while(this.successCallback.length){
            this.successCallback.shift()();
        }
    }
    //修改状态失败
    reject = value => {
        //如果状态不是等待直接退出函数
        if(this.status !== PENDING) return;
        this.status = REJECTED;
        //设置失败后的原因
        this.reason = value;

        //this.failCallback && this.failCallback(value);
        while(this.failCallback.length){
            this.failCallback.shift()();
        }
    }
    finally(callback){
        return this.then(value=>{
            return myPromise.resolve(callback()).then(()=> value)
        },err=>{
            return myPromise.resolve(callback()).then(()=> {throw err}) 
        })
    }
    then = (successCallback,failCallback)=>{
        
        successCallback = successCallback ? successCallback : value=>value;
        failCallback = failCallback ? failCallback : err=> {throw err};

        let promise2 = new myPromise((reslove,reject)=>{
            if(this.status == PULFILLED){
                //异步 为了能够获取到 promise2
                setTimeout(()=>{
                   try{
                        let x = successCallback(this.value);
                        //判断x是普通值还是promise对象
                        //如果是普通值直接调用resolve
                        //如果是promise对象,查看promise对象返回的结果
                        //在根据promise对象返回的结果 决定调用resolve 还是reject
                        resolvePromise(promise2,x,reslove,reject);
                   }
                   catch(err){
                        reject(err);
                   }
                },0);
            }else if(this.status == REJECTED){
                setTimeout(()=>{
                    try{
                        let x = failCallback(this.reason);
                        //判断x是普通值还是promise对象
                        //如果是普通值直接调用resolve
                        //如果是promise对象,查看promise对象返回的结果
                        //在根据promise对象返回的结果 决定调用resolve 还是reject
                        resolvePromise(promise2,x,reslove,reject);
                    }
                    catch(err){
                        reject(err);
                    }
                 },0);
            }else{
                //等待
                //将成功回调和失败回调存储起来
                this.successCallback.push(()=>{
                    setTimeout(()=>{
                        try{
                            let x = successCallback(this.value);
                            //判断x是普通值还是promise对象
                            //如果是普通值直接调用resolve
                            //如果是promise对象,查看promise对象返回的结果
                            //在根据promise对象返回的结果 决定调用resolve 还是reject
                            resolvePromise(promise2,x,reslove,reject);
                        }
                        catch(err){
                            reject(err);
                        }
                    },0)
                });
                this.failCallback.push(()=>{
                    setTimeout(()=>{
                        try{
                            let x = failCallback(this.reason);
                            //判断x是普通值还是promise对象
                            //如果是普通值直接调用resolve
                            //如果是promise对象,查看promise对象返回的结果
                            //在根据promise对象返回的结果 决定调用resolve 还是reject
                            resolvePromise(promise2,x,reslove,reject);
                        }
                        catch(err){
                            reject(err);
                        }
                    },0)
                });
            }
        });
        return promise2;
    }
    catch(failCallback){
        return  this.then(undefined,failCallback)
    }
    //注意需要在所有promise异步执行之后调用reslove
    static all (array){
        //结果数组
        let result = [];
        let index = 0;
        
        return new myPromise((reslove,reject)=>{
            function addData (i,value){
                result[i] = value;
                index++;
                if(index === array.length){
                    reslove(result);
                }
            }
            for(let i=0;i<array.length;i++){
                let current = array[i];
                if(current instanceof myPromise){
                    //promise对象
                    current.then(value=>{
                        addData(i,value)
                    },err=>{
                        reject(err)
                    });
                }else{
                    //普通值
                    addData(i,current);
                }
            }
        })
    }
    static resolve(data){
        if(data instanceof myPromise){
            return data;
        }else{
            return new myPromise((resolve,reject)=>{
                resolve(data);
            })
        }
    }
}
function resolvePromise (promise2,x,reslove,reject){
    //判断返回
    if(promise2 === x){
        return reject(new TypeError("promise对象被循环调用"))
    }
    //判断是否是promise对象
    if(x instanceof myPromise) {
        // x.then(value=> resolve(value),err=>reject(err));
        //简写
        x.then(reslove,reject);
    }else{
        reslove(x);
    }
}

空文件

简介

学习资料 展开 收起
JavaScript
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
JavaScript
1
https://gitee.com/menotwo/fed-e-task-01-01.git
git@gitee.com:menotwo/fed-e-task-01-01.git
menotwo
fed-e-task-01-01
大前端学习
master

搜索帮助