# task-01-01 **Repository Path**: zhangxiaoming123456/task-01-01 ## Basic Information - **Project Name**: task-01-01 - **Description**: No description available - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-01-26 - **Last Updated**: 2021-01-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # task-01-01 #### 介绍 {**以下是 Gitee 平台说明,您可以替换此简介** Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} #简答题 ##1、谈谈你是如何理解JS异步编程的,EventLoop、消息队列都是做什么的,什么是宏任务,什么是微任务? 异步编程:就相当于两个人一起工作,一个处理能够及时完成的任务,另一个处理有延迟的任务,这样不会影响程序进程,避免程序卡顿/卡死。 EventLoop:事件轮询机制,会监听 调用栈和消息队列,当调用栈中的任务被清空后,它会去消息队列中查看,把消息队列中的任务放到调用栈中去执行。 消息队列:当有类似于计时器的延迟任务时,web APIS计时结束后,就会把任务放到消息队列中等待进入调用栈中进行调用,消息队列就相当于调用栈的待办任务。 宏任务:宏任务是需要重新排队进行的任务 微任务:微任务是可以在宏任务的基础下,不需要重新排队,顺便就去调用的任务。 #代码题 #####一、将下面异步代码使用Promised的方式改进 ``` function fna(){ return setTimeout(()=>{ var a = 'hello' return a },10) } function fnb(){ return setTimeout(()=>{ var b = 'lagou' return b },10) } promise.all([fna(),fnb()]) .then(value=>{ setTimeout(()=>{ var c = 'I ♥ U'; console.log(value[0]+value[1]+c) },10) },err=>{ console.log(err) }) ``` ##二、基于一下代码完成下面的四个练习 #####练习1:使用函数组合fp.flowRight()重新实现下面这个函数 ``` const fp = require('lodash/fp') const isLastInStock = fp.flowRight(fp.prop('in_stock'),fp.last(cars)) console.log(isLastInStock(cars)) ``` ![image.png](https://upload-images.jianshu.io/upload_images/13686585-4c17a9ec1dbf6c25.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ``` const fp = require('lodash/fp') const isFirstInName = fp.flowRight(fp.prop('name'),fp.first(cars)) console.log(isFirstInName(cars)) ``` #####练习3:使用帮助函数_average重构 averageDollarValue,使用函数组合的方式实现 ``` const fp = require('lodash/fp') let _average = function (xs){ return fp.reduce(fp.add,0,xs)/xs.length } let getValue = function(car){ return car.dollar_value } let averageDollarValue = fp.flowRight(_average(),fp.map(getValue)) ``` #####练习4:sanitizeNames(['Hello World']) => ['hello_world'] ``` const fp = require('lodash/fp') let _underscore = fp.replace(/\w+/g,'_') let sanitizeNames= fp.map(_underscore,fp.map(fp.flowRight(fp.toLower(),fp.split(/\w+/g)))) ``` ##三、基于下面提供的代码,完成后续的四个练习 #####练习1:使用fp.add(x,y)和fp.map(f,x)创建一个能让functor里的值增加的函数exl ![image.png](https://upload-images.jianshu.io/upload_images/13686585-1852b786656700e9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ``` let ex1=() => maybe.map( fp.map(fp.add(1)) ) ``` #####练习2:实现一个函数ex2,能够使用fp.first获取列表的第一个元素 ![image.png](https://upload-images.jianshu.io/upload_images/13686585-78b532c5021f2ed1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ``` let ex2=() => Container.map( fp.first() ) ``` #####练习3:实现一个函数ex3,使用safeProp和fp.first找到user的名字的首字母 ![image.png](https://upload-images.jianshu.io/upload_images/13686585-48aa32d3f7c22c7d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ``` let ex3=(user) => safeProp('name',user) ``` #####练习4:使用Maybe重写ex4,不要有if语句 ![image.png](https://upload-images.jianshu.io/upload_images/13686585-b9e43a617183f686.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ``` let ex4=(n) => Maybe.of(n).map(n=>parseInt(n)) ``` ##四、手写实现MyPromise源码 ``` function resolvePromise(promise2,x,ressolve,){//判断then 的成功/失败 if(promise2 === x){ return reject(new TupeError('xxxx')) } if(x instanceof MyPromise){ x.then(resolve,reject) }else{ resolve(x) } } class MyPromise { constructor (executor){//执行器 立即执行 try{//用于捕获执行器中的错误 executor(this.resolve,this.reject) }catch(e){ this.reject(e) } } status = PENGING; //promise状态 默认pending value = undefined;//成功之后的值 reason = undefined;//失败后的原因 successCallback = [];//成功回调 failCallback = [];//失败回调 resolve=value=>{ if(this.status !== PENGING)return //如果状态不是等待,阻止程序向下执行 this.status = FULFILLED;//将状态更改为成功 this.value = value;//保存成功之后的值 while(this.successCallback.length)this.successCallback.shift()(this.value)//判断成功回调是否存在,如果存在就调用 } reject=reason=>{ if(this.status !== PENGING)return //如果状态不是等待,阻止程序向下执行 this.status = REJECTED;//将状态更改为失败 this.reason = reason;//保存失败后的原因 while(this.failCallback.length)this.failCallback.shift()(this.reason)//判断失败回调是否存在,如果存在就调用 } then(successCallback ,failCallback){ let promise2 = new MyPromise((resolve,reject)=>{//实现then的链式调用 //状态判断 if(this.status === FULFILLED){ setTimeout(()=>{ let x = successCallback(this.value) // resolve(x) //把上一个的成功返回结果,传给下一个then作为参数 resolvePromise(promise2,x,resolve,reject) },0) }else if(this.status === REJECTED){ failCallback(this.reason) }else { //等待 //将成功回调和失败回调存储起来 this.successCallback.push(successCallback) this.failCallback.push(failCallback) } }) return promise2 //使then返回一个promise对象 } static all(array){ let result = []; let index = 0; return new MyPromise((resolve,reject)=>{ function addData(key,value){ result[key] = value; index++ if(index === array.length){ resolve(result) } } for(let i=0;iaddData(i,value),reason=>reject(reason)) }else{ addData(i,array[i]); } } }) } static resolve(value){ if(value instanceof MyPromise)return value return new MyPromise(resolve=>resolve(value)) } finally(callback){ return this.then(value=>{ return MyPromise.resolve(callback()).then(()=>value) },reason=>{ return MyPromise.resolve(callback()).then(()=>{throw reason}) }) } catch(failCallback){ return this.then(undefined,failCallback ) } } module.exports = MyPromise; ``` ![CgqCHl7m3iuAC31fAC18FIagZlY698.png](https://upload-images.jianshu.io/upload_images/13686585-33ec880cbad1aed4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)