0
点赞
收藏
分享

微信扫一扫

前端大厂面试

敬亭阁主 2022-04-06 阅读 42
前端

1 手写promise相关代码

promise是异步编程的一种解决方案,promise有三种状态:

  • pending:等待中,表示还没有得到结果
  • fulfilled:意味着操作成功完成
  • rejected:意味着操作失败

promise函数接收两个参数,resolve和reject

  • resolve:将promise对象的状态从pending变为fulfilled,在异步操作成功时调用
  • reject:将promise对象的状态从pending变为rejected

promise.all(),如果所有promise都执行成功返回所有成功的promise值,如果有失败则返回第一个失败的值
promise.race(),返回第一个执行完成的promise值,他有可能是fulfilled和rejected状态

应用场景:
1、用户登录后,会同时异步请求所有数据,这时要确保所有数据请求成功,如果有一个不成功就会重定向页面,使用promise.all方法
2、抢票软件,请求了很多卖票渠道,每次只需返回第一个执行完成的promise,使用promise.race方法

Promise.all()手写

function pAll(_promises){
	return new Promise((resolve,reject)=>{
		//传进来的是一个可迭代对象,需要先转化为数组
		const promises=Array.from(_promises)
		const len=promises.length
		const r=[]
		let count=0
		for (let i=0;i<len;i++){
		//数组中可能包含常量,需要将其转换为promise对象
			Promise.resolve(promises[i]).then(0 => {
				r[i]=o
				if(++count===len){
					resolve(r)
				}
			}).catch(e=>reject(e))
		}
	})
}

Promise.race()手写

function pRace(_promises){
	return new Promise((resolve,reject)=>{
		const promises=[..._promises]
		promises.forEach(p=>Promise.resolve(p).then(o=>resolve(o)).catch(e=>reject(e)))
	})
}

2 history和hash的使用和区别

hash:hash虽然出现在URL中,但不会被包括在http请求中,对后端完全没有影响,因此改变hash不会重新加载页面
history:利用pushState()和replaceState()方法,当他们执行修改时,虽然改变了URL,但是浏览器不会立即向后端发生请求

history相对于直接修改hash具有以下优势:

  • pushstate设置的新的URL可以是与当前URL同源的任意URL,而hash只能修改#后面的部分,因此只能设置与当前URL同文档的URL
  • pushstate通过stateobject参数可以添加任意类型的数据到记录中,hash只可添加短字符串

history的缺点:
在history模式下,一旦发生刷新,如果服务器没有相应的响应或资源,会报404错误

3 跨域问题

当协议、域名、端口任一不一样就会产生跨域

解决跨域的方案:
(1)Access-Control-Allow-Origin:*
无法携带cookie时,设置withCredentials = false
(2)jsonp:就是script标签的src引入
(3)反向代理

4 手写new操作符

new操作符的流程:

  1. 生成一个空的obj对象
  2. 让对象的原型指向构造函数的原型
  3. 改变构造函数的指向
  4. 判断类型,如果为值类型,则返回obj,如果为引用类型,则返回引用类型的对象
function _new(constructor,...args){
	const obj={}
	obj.__proto__=constructor.prototype
	let res=constructor.apply(obj,args)
	return res instanceof Object?res:obj
}

优化实现:

function _new(constructor,...args){
	let obj=Obj.create(constructor.prototype)
	let res=constructor.apply(obj,args)
	return res instanceof Object?res:obj
}

5 手写解析url参数

以此URL链接为例

'http://www.getui.com?user=superman&id=345&id=678&city=%E6%9D%AD%E5%B7%9E&enabled'
function parseParam(url){
	const [href,params]=url.split('?')
	//保存参数的对象
	const result={}
	//判断传入链接是否含有参数
	params && params.split('&').map(item=>{
		//将参数划分成键和值的形式
		let [key,value=true]item.split('=')		//当参数没有值时给他一个boolean值
		//有的值时编码了的格式需要对其进行转化
		value=typeof value==='boolean'?value:decodeURIComponent(value)
		//此时需要分键是否重复进行处理
		if(!result[key]){	//如果没有重复的键值
			result[key]=value
		}else{
			//有重复,则要将其写成数组的格式
			result[key]=result[key] instanceof Array?[...result[key],value]:[result[key],value]
		} 
	})
}

6 http常见状态码

  • 200:请求成功
  • 301:永久重定向
  • 302:临时重定向
  • 304:自上次请求,未修改的文件
  • 400:错误的请求
  • 401:未被授权,需要身份验证,如token信息
  • 403:请求被拒绝
  • 404:资源缺失,接口不存在,或请求的文件不存在
  • 500:服务器端的未知错误
  • 502:网关错误
  • 503:服务暂时无法使用
举报

相关推荐

0 条评论