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操作符的流程:
- 生成一个空的obj对象
- 让对象的原型指向构造函数的原型
- 改变构造函数的指向
- 判断类型,如果为值类型,则返回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:服务暂时无法使用