Js手写面试题5-Promise
Promise
❓有任何疑问都可以私信我解答
⚡仓库地址:https://gitee.com/super_li_yu/promise
😛建议关注,持续更新。
✒️主要内容:Promise
Promise是一门是在ES6里提出的新技术,是JS在异步编程的一种解决方案,可以支持链式调用,可以解决地狱问题指定回调的问题更加灵活。
Promise成功会调用resovle中,失败会调用reject。then里面会包裹两个函数体,第一个函数体放成功的逻辑,第二个函数体放失败的逻辑。
1.原理
1.Promise的状态
- pending 进行中
- resolved/fullfilled 成功
- rejected 失败
2.Promise 对象的值
实例对象中的另外一个属性:[PromiseResult]
保存着对象[成功/失败]的结果
- resolve
- reject
3.Promise的工作流程
4.Promise相关的API
Promise构造函数:Promise(excutor){}
- excutor函数:执行器。
(resolve,reject)=>{}
- resolve函数:内部定义成功时我们调用的函数
value=>{}
- reject函数:内部定义的失败时候会调用函数
reson=>{}
- excutor函数:执行器。
说明
excutor会在Promise内部
立即同步
调用,异步操作在执行器中执行。
Promise.prototype.then方法:(onResolved,onRejected)=>{}
- onResolved函数:成功的回调函数(value)=>{}
- onReject函数:失败的回调(reson)=>{}
说明
指定用于得到成功的value的成功回调和用于得到失败的reson的失败回调返回一个新的Promise对象
Promise.prototype.catch方法:(onRejected)=>{}
- onRejected函数:失败的回调函数(reson)=>{}
Promise.resolve方法:(value)=>{}
- value成功的数据或者promise对象
说明
返回一个成功/失败的Promise对象
1.如果传入的的参数为非promise类型的对象,则返回的结果为成功promise对象
2.如果传入的参数为promise对象,则参数的结果决定了resolve的结果
Promise.reject方法:(reson)=>{}
- reson:失败的原因
说明
返回一个失败的Promise对象
无论你传入什么数值,都是失败的对象
Promise.all方法:(Promise)=>{}
- Promise:包含n个Promise对象的数组
说明
返回一个新的Promise,
只有所有的Promise都成功才成功,只要有一个失败就直接失败
如果都成功,就返回一个数组,里面是返回成功的对象.
如果有一个失败,就返回该失败的结果.
Promise.race方法:(Promises)=>{}
- promise:包含多个
说明
返回一个新的Promise,
第一个
完成的Promise的结果状态就是最终的结果状态
2.问题
1.Promise状态的改变
2.改变Promise状态和指定回调函数谁先谁后?
then方法先执行还是改变状态先执行.
- 都有可能正常情况下是先指定回调再改变状态,但也可以先改变状态再指定回调
- 如何先改变状态再指定回调?
- 再执行器中直接调用resolev()/reject()
- 延迟更长时间才调用then()
- 什么时候才能得到数据?
- 如果先指定回调,那当状态发生改变时,回调函数就会调用,得到数据.
- 如果先改变的状态,那当指定回调时,回调函数就会调用,得到数据.
- promise.then()返回的新promise的结果状态由什么决定?
- 简单表达:由then()指定的回调函数执行的结果决定
- 如果返回的是非promise的任意值,新promise变成
3.Promise的异常穿透
- 当使用Promise的then链式调用后,可以在最后指定失败的回调
- 当前任何操作出现了异常,都会传到最后失败的回调中处理
这块应用场景最多的还是在链式调用的最后,使用.catch来捕捉错误.
中间出现的任何错误,都可以到最后进行捕获
let p = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve('ok');
reject('出错了')
}, 1000)
})
p.then(value => {
console.log(111);
}).then(value => {
console.log(222); //success
}).then(value => {
console.log(333); //undefined
}).catch(reson => {
console.warn(reson);
})
4.如何中断Promise链条
只要我们给消息队列中想要中断的位置添加一个状态为pedding(进行中)
的Promise就可以了。
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok')
}, 1000)
});
p.then(value => {
console.log(111)
//返回一个padding状态的promise的回调对象
return new Promise(() => { })
}).then(value => {
console.log(222);
}).then(value => {
console.log(333);
}).catch(reson => {
console.log(reson);
})
这样控制台只会输出
111
,后面的222,333,就不会再输出了。
5.手写一个promise
这块内容在代码仓库里哦
代码
抽奖函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>抽奖系统</title>
</head>
<body>
<button id="btn">点击抽奖</button>
</body>
</html>
<script>
//生成随机函数
function rand(m,n){
return Math.ceil(Math.random() * (n-m+1)) + m-1;
}
/**
* 点击按钮,2s后显示是否中奖(30%概率)
* 中奖弹出
* 未中奖弹出 再次努力
*/
//原生js实现
// const btn = document.querySelector("#btn");
// btn.addEventListener('click',function(){
// //定时器
// setTimeout(()=>{
// //30% 1-100 1-30
// let n = rand(1,100)
// if(n <= 30){
// alert('中奖')
// }else{
// alert('没中奖')
// }
// },1000)
// })
// Promise实现
/**
* resolve 解决 函数类型的数据
* rejet 拒绝 函数类型的数据
*/
const btn = document.querySelector("#btn");
btn.addEventListener('click',function(){
const p = new Promise((resove,reject)=>{
setTimeout(()=>{
//30% 1-100 1-30
let n = rand(1,100)
if(n <= 30){
resove(n); //调用完成后,可以将Promise对象的状态设置为成功
}else{
reject(n); //调用完成后,可以将Promise对象的状态设置为失败
}
},1000)
})
//调用then方法
p.then((n)=>{
alert(`中奖号为${n}`);
},(n)=>{
alert(`失败,号码为${n}`);
})
});
</script>
其他源码看仓库即可
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix