简答题
1、
1.javascript为何是单线程?javascript
与javascript的设计初衷有关,最先javascript是运行在浏览器中的脚本语言,目的是为了实现页面上的动态交互,实现页面的核心是dom操做,因此决定了javascript是单线程,不然会出现线程同步的问题: 好比多个线程同时操做一个dom元素,这时浏览器不知道要以谁的操做为准,形成代码执行顺序混乱 javascript是单线程也就意味着浏览器有多个任务的时候要排队依次进行,一个一个完成,这种模式的优势是比较安全。缺点是若是咱们遇到一个特别消耗时间的任务,那么后面的任务就会一直等着这个任务的完成,这样会形成页面卡死的状况,会形成阻塞。 javascript语言没法处理大量的耗时任务,为了解决这个问题,javascript讲执行任务分红了两种模式:同步模式和异步模式
2.同步模式java
同步模式指的是咱们的javascript代码要依次执行,后面的代码要等待前一句代码执行完成才能执行,排队执行,javascript代码大多数是以同步模式进行执行的
3.异步模式promise
异步模式指的是咱们的javascript代码不会等待前面的代码执行完毕才开始执行。 咱们将执行的代码放入到调用栈中执行,若是是同步的直接执行,若是是异步的则放入消息队列中等待执行,等到全部的代码执行完毕,咱们的event loop就上场了,它会监听调用栈和消息队列中的任务,当调用栈中全部的任务结束之后,它会从消息队列中依次取出回调函数压入到调用栈,开始执行,直到整个循环结束
4.Event Loop浏览器
主线程从消息队列中读取事件,这个过程是循环不断的,因此整个的这种运行机制称为Event Loop(事件循环),Event Loop是javascript的执行机制
5.消息队列安全
消息队列是暂时存放异步任务的地方,咱们的异步代码会存放到消息队列中,等到同步代码执行完毕之后,event loop会从消息队列中依次取出异步任务放到调用栈中再次执行。
6.宏任务,微任务dom
宏任务:当前调用栈中执行的代码成为宏任务,包括 主代码快 ,定时器 微任务:宏任务执行完,在下一个宏任务开始以前须要执行的任务,能够理解为回调函数 运行机制: 在执行栈中执行一个宏任务 执行过程当中遇到微任务,将微任务添加到消息队列中 当前宏任务执行完毕,当即执行微任务队列中的任务 微任务执行完毕后,把下一个宏任务放到消息队列中,经过eventloop放到调用栈中执行。
代码题
1、异步
new Promise((resolve, reject) => { var a = 'hello' resolve(a) }).then(value=> { var b = 'lagou' return value + b }).then(value=> { var c = 'I❤U' console.log(value + c ) })
2、函数
练习1: let isLastInStock = function(cars) { //获取最后一条数据 let last = cars => cars.pop() //获取最后一条数据in_stock属性值 let getValue = last => last.in_stock return fp.flowRight(value, last) } 练习2: let isFirstName = function(cars) { //获取第一条数据 //获取第一条数据name属性值 return fp.flowRight(fp.prop('name'), fp.first) } 练习3: let _average = xs => { return fp.reduce(fp.add, 0, xs) } let averageDollarValue = cars => { return _average(fp.flowRight(fp.map(fp.prop('dollar_value')))(cars)) } 练习4: let _underscore = fp.replace(/\s+/g, '_') let arr = fp.flowRight(fp.map(fp.prop('name')))(cars) let sanitizeNames = arr => { return fp.flowRight(fp.map(fp.flowRight(_underscore, fp.toLower)))(arr) }
3、oop
//support.js class Container { static of(value) { return new Container(value) } construtor(value) { this._value = value } map(fn) { return Container.of(fn(this._value)) } } class MayBe { static of (value) { return new MayBe(value) } constructor (value) { this._value = value } map (fn) { return this.isNothing() ? MayBe.of(null) : MayBe.of(fn(this._value)) } isNothing () { return this._value === null || this._value === undefined } } module.exports = { MayBe, Container } 练习1: const fp = require('lodash/fp') const { MayBe, Container } = require('./support') let maybe= MayBe.of([5,6,1]) let ex1 = () => { return maybe.map(arr => fp.flowRight(fp.map(fp.add(1)))(arr)) } 练习2: let ex2 = () => { return xs.map(arr => fp.first(arr)) } 练习3: let ex3 = () => { return safeProp('name', user).map(x => fp.first(x)) } 练习4: let ex4 = (n) => { return MayBe.of(n).map(n => parseInt(n)) }
4、ui
const PENDING = 'pending' const FULFILLED = 'fulfilled' const REJECTED = 'rejected' class Promise { constructor(executor) { //状态初始化为pending this.status = PENDING //成功传参 this.value = undefined //失败缘由 this.reason = undefined //存储成功的回调函数 this.successCallbacks = [] //存储失败的回调函数 this.failCallbacks = [] //成功 let resolve = (value) => { if(this.status == PENDING) { this.status = FULFILLED this.value = value while (this.successCallbacks.length) this.successCallbacks.shift()() } } //失败 let reject = (reason) =>{ if(this.status == PENDING) { this.status = REJECTED this.reason = reason while (this.failCallbacks.length) this.failCallbacks.shift()() } } try { executor(resolve, reject) } catch(err) { reject(err) } } then(successCallback, failCallback) { //参数可有能够无 successCallback = successCallback ? successCallback : value => value failCallback = failCallback ? failCallback : reason => { throw reason} let promise2 = new Promise((resolve, reject)=>{ if(this.status == FULFILLED) { setTimeout(()=>{ //异步让promise2先建立 try { let x = successCallback(this.value) // 判断 x的值是普通值仍是Promise对象 // 普通值 直接调用reslove // 如果Promise对象,查看Promise对象返回的接口 // 再根据结果,决定调用resolve仍是reject resolvePromise(promise2, x, resolve, reject) } catch(err) { reject(err) } }, 0) } else if(this.status == REJECTED) { setTimeout(()=>{ //异步让promise2先建立 try { let x = failCallback(this.reason) // 判断 x的值是普通值仍是Promise对象 // 普通值 直接调用reslove // 如果Promise对象,查看Promise对象返回的接口 // 再根据结果,决定调用resolve仍是reject resolvePromise(promise2, x, resolve, reject) } catch(err) { reject(err) } }, 0) } else { //存储成功的回调函数 this.successCallbacks.push(()=> { setTimeout(()=>{ //异步让promise2先建立 try { let x = successCallback(this.value) // 判断 x的值是普通值仍是Promise对象 // 普通值 直接调用reslove // 如果Promise对象,查看Promise对象返回的接口 // 再根据结果,决定调用resolve仍是reject resolvePromise(promise2, x, resolve, reject) } catch(err) { reject(err) } }, 0) }) //存储失败的回调函数 this.failCallbacks.push(()=> { setTimeout(()=>{ //异步让promise2先建立 try { let x = failCallback(this.reason) // 判断 x的值是普通值仍是Promise对象 // 普通值 直接调用reslove // 如果Promise对象,查看Promise对象返回的接口 // 再根据结果,决定调用resolve仍是reject resolvePromise(promise2, x, resolve, reject) } catch(err) { reject(err) } }, 0) }) } }) return promise2 } 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) } 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; i < array.length; i++) { let current = array[i]; if (current instanceof MyPromise) { // promise 对象 current.then(value => addData(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)); } } function resolvePromise (promise2, x, resolve, reject) { if(promise2 === x) { return reject(new TypeError('返回了相同的Promise对象')) } if(x instanceof Promise) { //promise对象 x.then(resolve, reject) } else { //普通值 resolve(x) } } module.exports = Promise