手写Promise

要看完整代码直接拉到最下方即可

(1).初始结构搭建与resolve,reject结构搭建

//声明构造函数 Promise对象有两个属性一个PromiseState 一个PromiseResult
function Promise(executor){
  //声明属性
  	this.PromiseState='pending'
  	this.PromiseResult=null
  //保存实例对象的this
  	const self=this
  //在resolve方法中我们要改变Promise对象状态,改变PromiseResult
  function resolve(data){
	self.PromiseState='fulfilled'
	self.PromiseResult=data
  }
  //同理
  function rejected(data){
	if(self.PromiseState!=='pending') return
	self.PromiseState='rejected'
	self.PromiseResult=data
  }
    //同步调用[执行器函数]
  executor(resolve,reject)
}
//添加then方法
Promise.prototype.then=function(onResolved,onRejected){
}

(2).throw抛出异常改变状态

function Promise(executor){
	this.PromiseState='pending'
  	this.PromiseResult=null
  	const self=this
	function resolve(data){
	  self.PromiseState='fulfilled'
	  self.PromiseResult=data
	}
  	function reject(data){
	  self.PromiseState='rejected'
	  self.PromiseResult=data
	}
  //在执行器函数 throw抛出异常想到用try...catch;
 try{
 	executor(resolve,reject)
 }catch(e){
   //修改promise对象的状态为失败
   reject(e)//为什么是e不是data了?因为结果值就是抛出的结果值
 	}
}
Promise.prototype.then=function(onResolved,onRejected){
}

(3)Promise对象状态只能改变一次以及then方法执行回调

function Promise(executor){
  this.PromiseState='pending'
  this.PromiseResult=null
  const self=this
  function resolve(data){
	//判断状态
	if(self.PromiseState!=='pending')return
	self.PromiseState='fulfilled'
	self.PromiseResult=data
  }
  function reject(data){
	if(self.PromiseState!=='pending')return
	self.PromiseState='rejected'
	self.PromiseResult=data
  }
  try{
	executor(resolve,reject)
  }catch(e){
  	reject(e)
  }
}
Promise.prototype.then=function(onResolved,onRejected){
  //调用回调函数
  if(this.PromiseState==='fulfilled){
	 //因为这里是实例对象调用的所以直接用this就行
	 onResolved(this.PromiseResult)
	}
	if(this.PromiseState==='rejected'){
	  onRejected(this.PromiseResult)
	}
}

(4)异步任务回调的执行

function Promise(executor){
  	this.PromiseState='pending'
  	this.PromiseResult=null
  	const self=this
	//声明属性
	this.callback={}
  	function resolve(data){
	  	if(self.PromiseState!=='pending')return
		self.PromiseState='fulfilled'
	  	self.PromiseResult=data
	  //调用成功的回调函数
	  if(self.callback.onResolved){
		self.callback.onResolved(data)
	  }
	}
  	function reject(data){
	  	if(self.PromiseState!=='pending')return
	  	self.PromiseState='rejected'
	  	self.PromiseResult=data
	  //调用失败的回调
	  if(self.callback.onRejected){
		self.callback.onRejected(data)
	  }
}
  try{
  	executor(resolve,reject);
  }catch(e){
	resolve(e)
  }
Promise.prototype.then=function(onResolved,onRejected){
  	if(this.PromiseState==='fulfilled'){
	 onResolved(this.PromiseResult)
	}
	if(this.PromiseState === 'rejected'){
	 onRejected(this.PromiseResult)
	}
  	if(this.PromiseState==='pending'){
	  //保存回调函数
	  this.callback={
	  	onResolved:onResolved
		onRejected:onRejected
	  }
	}
}

(5)指定多个回调的实现

function Promise(executor){  
  this.PromiseState='pending';  
  this.PromiseResult=null;  
  const self=this;  
  //this.callback={}; //这样保存有个弊端,后面的回调函数会把它覆盖掉
  this.callbacks=[]
  function resolve(data){  
    if(self.PromiseState!=='pending') return;  
    self.PromiseState='fulfilled';  
    self.PromiseResult=data;  
    /**if(self.callback.onResolved){  
      self.callback.onResolved(data);  
    }*/
	//遍历
	self.callbacks.forEach(item=>{
		item.onResolved(data)
	})
  }  
  
  function reject(data){ 
    if(self.PromiseState!=='pending') return; 
    self.PromiseState='rejected';  
    self.PromiseResult=data;  
    /**if(self.callback.onRejected){  
      self.callback.onRejected(data);  
    }*/
	self.callbacks.forEach(item=>{
	  item.onRejected(data)
	})
  }  
  
  try{  
    executor(resolve, reject);  
  }catch(e){  
    reject(e);  
  }  
}  
  
Promise.prototype.then=function(onResolved,onRejected){  
  if(this.PromiseState==='fulfilled'){ 
    onResolved(this.PromiseResult);  
  } else if(this.PromiseState==='rejected'){ 
    onRejected(this.PromiseResult);  
  }  
  if(this.PromiseState==='pending'){  
    this.callbacks.push({  
      onResolved:onResolved, 
      onRejected:onRejected  
    })  
  }  
}; 

(6)同步修改then方法和异步修改then方法 结果返回

这里我一开始犯了个错误,想着在执行器函数中写过try...catch捕获错误了,不用再在then方法中捕获。其实是不对的,因为执行器函数中的try...catch是用来捕获在初始化解析或拒绝状态时可能发生的错误。then方法中的try...catch则是用来捕获onResolved或onRejected回调函数中可能抛出的异常。这些异常通常发生在Promise已经解析或拒绝之后,注册新的回调函数并执行他们。

function Promise(executor){
	this.PromiseState='pending'
  	this.PromiseResult=null
  	const self=this
	const callbacks=[]
function resolve(data){
  if(self.PromiseState!='pending) return
	 self.PromiseState='fulfilled'
	 self.PromiseResult=data
	 self.callbacks.forEach(item=>{
	 	item.onResolved(data)
	})
}
function reject(data){
  if(self.PromiseState!='pending)
	self.PromiseState='rejected'
	self.PromiseResult=data
	self.callbacks.forEach(item=>{
	 item.onRejected(data)
	})
}
    try{
	executor(resolve,reject)
  }catch(e){
	reject(e)
  }
}
Promise.prototype.then(onResolved,onRejected){
  const self=this
  //返回一个新的Promise对象
  return new Promise((resolve,reject)=>{
  if(this.PromiseState==='fulfilled'{
	 //获取回调函数的执行结果
	 try{
	 let result=onResolved(this.PromiseResult)
	//判断执行结果是否为一个Promise对象
	if(result instanceof Promise){
	  result.then(v=>{
			resolve(v)
	  },r=>{
			reject(r)
	  })
		}else{
		  //结果对象的状态为成功
				resolve(result)
		}
  }catch(e){
		reject(e)
  }
	}
	if(this.PromiseState==='rejected'{
	 onRejected(this.PromiseResult)
	}
	if(this.PromiseState==='pending'{
		this.callbacks.push({
	   		onResolved:function(){
	  //判断
	  try{
		//执行成功的回调函数
	  let result=onResolved(self.PromiseResult)
	  if(result instance of Promise){
	  	result.then(v=>{
		  resolve(v)
		},r=>{
		  reject(r)
		})
	  }else{
			resolve(v)
	  }
	  }catch(e){
		reject(e)
	  }
	},
	   		onRejected:function(){
			  try{
	//执行失败的回调函数
		let result = onRejected(self.PromiseResult)
	  if(result instance of Promise){
	  	result.then(v=>{
		  resolve(v)
		},r=>{
		  reject(r)
		})
	  }else{
			resolve(v)
	  }
	  }catch(e){
		reject(e)
	  }  
			}
		}) 
	}
})
}

(7)完善then方法

从上面的代码中看出来,有很多重复的代码,为了简洁,我们将它进行封装

function Promise(executor){
  this.PromiseState='pending'
  this.PromiseResult=null
  const self=this
  const callbacks=[]
  function resolve(data){
	if(self.PromiseState!='pending')return
	self.PromiseState='fulfilled'
	self.PromiseResult=data
	self.callbacks.forEach(item=>{
		item.onResolved(data)
	})
  }
  function reject(data){
	if(self.PromiseState!='pending')return
	self.PromiseState='rejected'
	self.PromiseResult=data
	self.callbacks.forEach(item=>{
	  item.onRejected(data)
	})
  }
  try{
	executor(resolve,reject)
  }catch(e){
	reject(e)
  }
}
Promise.prototype.then=function(onResolved,onRejected){
  const this=self
  return new Promise((resolve,reject)=>{
	//封装函数
	function callback(type){
		let result=type(self.PromiseResult)
		try{
		if(result instanceof Promise){
			result.then(v=>{
			  resolve(v)
			},r=>{
			  reject(r)
			}else{
					resolve(result)
		}
		}catch(e){
					reject(e)
		}
	}
  	if(this.PromiseState==='fulfilled'){
		callback(onResolved)
	}
	if(this.PromiseState==='rejected'){
		callback(onRejected)
	}
	if(this.PromiseState==='pending'){
		this.callbacks.push({
		onResolved:function(){
			callback(onResolved)
		},
		onRejected:function(){
			callback(onRejected)
		}
		})
	}
  })
}

(8)catch方法的封装我们要实现两个功能:1.catch传统2.值传递;resolve方法的封装

function Promise(executor){
  this.PromiseState='pending'
  this.PromiseResult=null
  const self=this
  const callbacks=[]
  function resolve(data){
	if(self.PromiseState!='pending')return
	self.PromiseState='fulfilled'
	self.PromiseResult=data
	self.callbacks.forEach(item=>{
		item.onResolved(data)
	})
  }
  function reject(data){
	if(self.PromiseState!='pending')return
	self.PromiseState='rejected'
	self.PromiseResult=data
	self.callbacks.forEach(item=>{
	  item.onRejected(data)
	})
  }
  try{
	executor(resolve,reject)
  }catch(e){
	reject(e)
  }
}
Promise.prototype.then=function(onResolved,onRejected){
  const this=self
  //判断回调函数
  if(typeof onRejected !=='function'){
	onRejected=reason=>{
	  throw reason
	}
	if(typeof onResolved !=='function'){
	  onResolved=value=>value
	}
  return new Promise((resolve,reject)=>{
	function callback(type){
		let result=type(self.PromiseResult)
		try{
		if(result instanceof Promise){
			result.then(v=>{
			  resolve(v)
			},r=>{
			  reject(r)
			}else{
					resolve(result)
		}
		}catch(e){
					reject(e)
		}
	}
  	if(this.PromiseState==='fulfilled'){
		callback(onResolved)
	}
	if(this.PromiseState==='rejected'){
		callback(onRejected)
	}
	if(this.PromiseState==='pending'){
		this.callbacks.push({
		onResolved:function(){
			callback(onResolved)
		},
		onRejected:function(){
			callback(onRejected)
		}
		})
	}
  })
}
//封装catch方法
Promise.prototype.catch=function(onRejected){
  return this.then(undefind,onRejected)
}
  //封装resolve方法
Promise.resolve=function(value){
  //返回promise对象
  return new Promise((resolve,reject)=>{
	if(value instanceof Promise){
	  value.then(v=>{
		resolve(v)
	  },r=>{
		reject(r)
	  })
	}else{
	  //状态设置成功
	  resolve(value)
	}
  })
}
//封装reject方法
Promise.reject=function(reason){
  return new Promise((resolve,reject)=>{
  	reject(reason)
  })
}
  //封装all方法
Promise.all=function(promises){
	return new Promise((resolve,reject)=>{
	  let count=0
	  let arr=[]
	  //遍历
	  for(let i=0;i<promises.length;i++){
		promises[i].then(v=>{
		  //得知对象状态是成功的
		  //每个promise对象都成功
		  count++;
		  //将当前promise对象成功的结果存入数组当中
		  arr[i]=v
		  //判断
		  if(count ===promises.length){
			resolve(arr)  
			}
	  },r=>{
		  reject(r)
		})
	  }
	})
}
//封装race方法
Promise.race=function(promises){
	return new Promises((resolve,reject)=>{
		for(int i=0;i<promises.length;i++){
			promises[i].then(v=>{
			  resolve(v)
			},r=>{
			  reject(r)
			})
		}
	})
}

(9)then方法回调的异步执行 完结


//1.声明构造函数
function Promise(excutor){
    //5.添加属性
    this.PromiseState='pending'
    this.PromiseResult=null
    //声明属性
    this.callbacks=[]
    //保存实例对象的this
    const self=this

    //4.声明resolve,reject
    function resolve(data){
        //判读状态
        if(self.PromiseState!=='pending') return
        //4.1 修改对象的状态(PromiseState)
        self.PromiseState='fulfilled'
        //4.2 设置对象结果值(PromiseResult)
        self.PromiseResult=data
        //调用成功的回调函数 ???
        setTimeout(()=>{
        self.callbacks.forEach(item => {
            item.onResolved(data)
        })
    })
    }
    function reject(data){
        if(self.PromiseState!=='pending') return
        self.PromiseState='rejected'
        self.PromiseResult=data
        setTimeout(()=>{
        self.callbacks.forEach(item => {
            item.onRejected(data)
        });
    })
    }
    try{
    //3.执行器函数同步调用
    excutor(resolve,reject);
    }catch(e){
        //修改Promise对象状态为[失败]
        reject(e);
    }
}
//2.添加then方法
Promise.prototype.then=function(onResolved,onRejected){
    const self=this;
    //判断回调函数参数
    if(typeof onRejected !=='function'){
        onRejected=reason=>{
            throw reason
        }
    }
    if(typeof onResolved!=='function'){
        onResolved=value=>value //简略写法
        //value => {return value}
    }
    return new Promise((resolve,reject)=>{
    //封装函数
    function callback(type){
        try{
            //获取回调函数的执行结果
        let result = type(self.PromiseResult)
            //判断如果回调函数的结果是Promise对象
            if(result instanceof Promise){
                //如果是Promise对象
                result.then(v=>{
                    resolve(v);
                },r=>{
                    reject(r);
                })
            }else{
                resolve(result)
            }
        }catch(e){
                reject(e)
            }
        }
    //调用回调函数
    if(this.PromiseState==='fulfilled'){
        setTimeout(()=>{
        callback(onResolved)
    })
    }
    if(this.PromiseState==='rejected'){
        setTimeout(()=>{
       callback(onRejected)
    })
    }
    //判断pending状态
    if(this.PromiseState==='pending'){
        //保存回调函数
        this.callbacks.push({
            onResolved:function(){
                callback(onResolved)
            },
            onRejected:function(){
                callback(onRejected)
            }
        })
    }
    })

}

//添加catch方法
Promise.prototype.catch=function(onRejected){
    return this.then(undefined,onRejected)
}

//添加resolve方法
Promise.resolve=function(value){
//返回promise对象
    return new Promise((resolve,reject)=>{
        if(value instanceof Promise){
            value.then(v=>{
                resolve(v)
            },r=>{
                reject(r)
            })
        }else{
            resolve(value);
        }
    })
}

//添加reject方法
Promise.reject=function(reason){
    return new Promise((resolve,reject)=>{
        reject(reason)
    })
}

//添加all方法
Promise.all=function(promises){
    //返回结果为Promise对象
    return new Promise((resolve,reject)=>{
        //声明变量
        let count=0;
        let arr=[];
        //遍历
        for(let i=0;i<promises.length;i++){
            //
            promises[i].then(v=>{
                //得知对象的状态是成功的
                //每个promise对象都成功
                count++;
                //将当前的promise对象成功的结果存入到数组中
                arr[i]=v;
                if(count===promises.length){
                    resolve(arr);
                }
            },r=>{
                reject(r);
            })
        }
    })
}

//添加race方法
Promise.race=function(promises){
    return new Promise((resolve,reject)=>{
        for(let i=0;i<promises.length;i++){ 
            promises[i].then(v=>{
                resolve(v);
            },r=>{
                reject(r)
            })
        }
    });
}

全部评论

相关推荐

1.&nbsp;常见的行内元素2.&nbsp;网页中head部分的meta标签有什么作用3.&nbsp;子元素如何对父元素实现水平垂直居中4.&nbsp;有用过grid吗?(了解过,但是没在项目中使用过)5.&nbsp;css中rem和em的区别6.&nbsp;列举position的值7.&nbsp;伪类和伪元素有什么区别8.&nbsp;canvas和svg有什么区别(回答了不熟悉canvas,svg使用一般是直接在网站中选取svg图标插入)9.&nbsp;了解过svg的图标是如何实现的吗10.&nbsp;列举数组有哪些方法11.&nbsp;针对回答的方法,问了push、splice、shift、slice、fliter哪些是改变原数组,哪些不改变12.&nbsp;讲一下防抖和节流的使用场景13.&nbsp;字符串反转&nbsp;说一下思路14.&nbsp;数组随机打乱&nbsp;说一下思路15.&nbsp;vue3中的hooks方法用过吗?&nbsp;(我只说了生命周期,好像不是16.&nbsp;computed和watch的区别17.&nbsp;列表渲染时,key有什么作用18.&nbsp;图片懒加载具体是什么实现的(使用了vueuse中的useIntersectionObserver)19.&nbsp;知道vueuse的作者吗(这个真不知道)20.&nbsp;之前自己有写过一个hooks吗21.&nbsp;有哪些常见的持久化方案22.&nbsp;cookies、sessionstorage、localstorage常见的使用场景23.&nbsp;了解或者使用过ts吗(只看了一点ts,面试官还是比较看重这里的,表示ts一定要会24.&nbsp;package.json文件是干什么用的?25.&nbsp;package-lock.json文件和package.json有什么区别?26.&nbsp;列举发起网络请求常见的http的header27.&nbsp;说一下http的状态码28.&nbsp;有哪些途径学习前端的知识29.&nbsp;有提到过在掘金看帖子,还问我有没有固定关注的人或者订阅的专栏30.&nbsp;未来对于前端学习有什么规划吗31.&nbsp;怎么看别人都说ai会取代前端?说说看法反问:针对面试表现能不能提一些未来学习的建议?一定要会ts,前端工程化方面虽然使用不多,但是也要掌握滴滴流程很快,十分钟内就知道结果了。
点赞 评论 收藏
分享
好伤心,面试官结束时候评价是整体还行,等视频挂了5分钟内收到感谢信这前后反差,我只好安慰面试官尊重自己,但是谁来安慰我呀面试上来开始问八股1,说说&nbsp;url到浏览器页面显示整个过程2,http&nbsp;缓存3,流式输出,你知道哪些可以实现的方式?AI生成到前端你觉得采用那种方式?3,css&nbsp;设置的元素要不断旋转,怎么写(不到一分钟面试官问我是否会,不会可以换一题,那我还行想到用什么,那换一题吧)keyfram&nbsp;里面设transform;animation&nbsp;里面应用设定的spin;代码如下:(linear&nbsp;匀速转,infinite&nbsp;无限循环)@keyframes&nbsp;spin&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;transform:&nbsp;rotate(0deg);&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;transform:&nbsp;rotate(360deg);&nbsp;&nbsp;&nbsp;&nbsp;}}.spinner&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;animation:&nbsp;spin&nbsp;2s&nbsp;linear&nbsp;infinite;&nbsp;/*持续2秒&nbsp;转一圈*/}4,输出解释题:function&nbsp;app()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;[count,&nbsp;setCount]&nbsp;=&nbsp;useState(0)&nbsp;&nbsp;&nbsp;&nbsp;useEffect(()&nbsp;=&gt;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;interval&nbsp;=&nbsp;setInterval(()&nbsp;=&gt;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log('useEffect')&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setCount(count&nbsp;+&nbsp;1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;1000)&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;[])&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h1&gt;{count}&lt;/h1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)}会输出打印什么?h1位置&nbsp;count&nbsp;显示什么那当然每隔1s&nbsp;打印出0,页面显示也是05,好的,你分析他原来想要实现什么效果,然后现在这段代码怎么改能实现预期效果,你有几种方式?【用useRef&nbsp;、手写update函数,设定count&nbsp;动态依赖项,使用setTimeout&nbsp;递归(但是容易爆栈)】我当时有点懵,当然是没考虑到function&nbsp;app()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;[count,&nbsp;setCount]&nbsp;=&nbsp;useState(0)&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;countRef&nbsp;=&nbsp;useRef(count);&nbsp;&nbsp;&nbsp;&nbsp;useEffect(()&nbsp;=&gt;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setInterval(()&nbsp;=&gt;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log('count',&nbsp;count);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;setCount(count&nbsp;+&nbsp;1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setCount(countRef.current&nbsp;+&nbsp;1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;1000)&nbsp;&nbsp;&nbsp;&nbsp;},[])&nbsp;&nbsp;&nbsp;&nbsp;useEffect(()&nbsp;=&gt;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;update&nbsp;=&nbsp;()&nbsp;=&gt;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log('update')&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setCount(count&nbsp;+&nbsp;1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setTimeout(update,&nbsp;1000)&nbsp;//&nbsp;递归调用,&nbsp;会导致栈溢出&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update();&nbsp;//&nbsp;初始调用&nbsp;&nbsp;&nbsp;&nbsp;})&nbsp;&nbsp;&nbsp;&nbsp;useEffect(()&nbsp;=&gt;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;interval&nbsp;=&nbsp;setInterval(()&nbsp;=&gt;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log('useEffect')&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setCount(count&nbsp;+&nbsp;1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;1000)&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;[count])&nbsp;//&nbsp;动态依赖,但是频繁定时器创建和销毁&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h1&gt;{count}&lt;/h1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)}7,输出顺序是什么?function&nbsp;app()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;promise.resolve().then(()&nbsp;=&gt;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log('promise')&nbsp;&nbsp;&nbsp;&nbsp;})&nbsp;&nbsp;&nbsp;&nbsp;useEffect(()&nbsp;=&gt;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log('useEffect')&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;[count])&nbsp;&nbsp;&nbsp;&nbsp;useLayoutEffect(()&nbsp;=&gt;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log('useLayoutEffect')&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;[count])&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h1&gt;{count}&lt;/h1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)}输出:useLayoutEffect promiseuseEffectuseLayoutEffect(dom更新后,相当浏览器刷新渲染了,立即同步执行)、promise&nbsp;(微任务,在同步执行完清空微任务队列)useEffect(异步执行,事件循环后执行)期间问了useLayoutEffect&nbsp;和&nbsp;useEffect&nbsp;区别8,看下面输出什么?(弱弱心想:不能出点其他的吗?)function&nbsp;Foo()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;getName&nbsp;=&nbsp;function&nbsp;()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(1);&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;this;}Foo.getName&nbsp;=&nbsp;function&nbsp;()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;alert(2);}Foo.prototype.getName&nbsp;=&nbsp;function&nbsp;()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;alert(3);}var&nbsp;getName&nbsp;=&nbsp;function&nbsp;()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;alert(4);}function&nbsp;getName()&nbsp;{&nbsp;alert(5);&nbsp;}Foo.getName();&nbsp;//&nbsp;2getName();&nbsp;//&nbsp;4Foo().getName();&nbsp;//&nbsp;1getName();&nbsp;//&nbsp;1new&nbsp;Foo.getName();&nbsp;//&nbsp;2new&nbsp;Foo().getName();&nbsp;//&nbsp;3new&nbsp;new&nbsp;Foo().getName();&nbsp;//&nbsp;3看这是金典js输出,但是解释起来费劲呀,解释不断问我:变量提升到哪,函数提升到哪,可以修改一下代码看看提升到的位置,new&nbsp;关键字分析一下,作为普通函数调用还是....&nbsp;(问下牛友,这种题目去那找能复习到呀)9,写个sum函数实现下面输出:console.log(sum(1,2,3).sumOf());&nbsp;//&nbsp;6console.log(sum(1,4)(2).sumOf());&nbsp;//&nbsp;7console.log(sum(1)(2)(3)(4).sumOf());&nbsp;//&nbsp;10function&nbsp;sum(...args)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;total&nbsp;=&nbsp;args.reduce((acc,cur)&nbsp;=&gt;&nbsp;acc&nbsp;+&nbsp;cur,0);&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;innerSum(...newArgs)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total&nbsp;+=&nbsp;newArgs.reduce((acc,cur)&nbsp;=&gt;&nbsp;acc&nbsp;+&nbsp;cur,0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;innerSum;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;innerSum.sumOf&nbsp;=&nbsp;()&nbsp;=&gt;&nbsp;total;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;innerSum;}console.log(sum(1,2,3).sumOf());&nbsp;//&nbsp;6console.log(sum(1,4)(2).sumOf());&nbsp;//&nbsp;7console.log(sum(1)(2)(3)(4).sumOf());&nbsp;//&nbsp;10
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务