JS常见面试题之详解Promi使用与原理

更新时间:2023-06-28 20:35:07 阅读: 评论:0

JS常见⾯试题之详解Promi使⽤与原理
⼀:Promi的概念
Promi的中⽂意思是‘承诺’,什么叫承诺?承诺就是现在没有发⽣,在将来的某个时刻⼀定会发⽣的事情。
放在编程语⾔的环境下,Promi就是异步事件的结果的占位符。我们不⽤去管异步事件的结果什么时候来,只需要关⼼异步事件的结果产⽣的时候,你想要做什么就对了。
⼆:Promi的⽣命周期
异步事件不是⽴即执⾏程序,它的结果可能要在动作发⽣后⼀段时间才到,所以它有个⽣命周期。例如⽤电饭锅煮⽶饭,从【⽶下锅开始定时】到【定时结束】,这是煮⽶饭的⽣命周期。
⼀个Promi的⽣命周期主要有2个阶段:
1: unttled(pending)处理过程中 -> ⽶饭定时开始到定时结束这段期间
2: ttled (fulfilled或者rejected) 处理完 -> ⽶饭定时结束状态
我们看到ttled阶段会出现两个可能的状态fulfilled或者rejected,它们分别是什么意思呢:
1: fulfilled Promi操作完成的结果为成功 -> 煮⽶饭⽔的⽐例合适,饭熟了,成功
2: rejected Promi操作完成的结果为失败 -> 煮⽶饭⽔放少了,饭是夹⽣的,失败
Promi内部的属性PromiState被⽤来表⽰Promi的3种状态:pending,fulfilled 和 rejected。但是我们⽆法读取到这三个状态,⽽是通过Promi提供的接⼝⽅法来书写对应的处理程序,后⾯会讲到。
三:如何让创建⼀个Promi
相信前⾯通过对⽐煮饭这个过程,你已经对Promi的概念和⽣命周期有了⼀定的体会,接下来我们就看看如何真正第创建⼀个
Promi(如何煮⽶饭)。
声明:因为Promi有未完成的Promi和已完成的Promi不同类型,本篇我们只讨论未完成的Promi。已完成的Promi后⾯会讲,⽬前来说你不必关⼼,就当世界上没有这个东西。
通过Promi构造函数,可以创建⼀个Promi。构造函数只有⼀个参数:⼀个函数,我们叫它执⾏器(executor)函数。你可以理解为煮饭⽤的电饭煲。
既然执⾏器(executor)函数也是⼀个函数,那它也有参数。对,它有2个参数:
1: resolve() 执⾏器(executor)函数成功时的处理函数
2: reject() 执⾏器(executor)函数失败时的处理函数
我们⽤⼀段代码来解释⼀下:
let executor = function (resolve, reject) {};
let promi = new Promi(executor);
通过上⾯的代码⽰例,应该就能很清楚创建⼀个Promi的语法解构是怎样的了。接下来我们⽤⼀个在Node.js中读取⽂件的例⼦来演⽰:
let executor = function (resolve, reject) {
let fs = require('fs');
if (error) {
reject(error); //在异步⾏为失败时,调⽤reject()⽅法
return;卖报歌教案
}
resolve(content); //在异步⾏为成功时,调⽤resolve()⽅法
});
};
let promi = new Promi(executor);
解释⼀下上⾯的代码:
1: 创建Promi,包裹异步程序
Promi本⾝并不执⾏任何真正的异步程序。我们只是把异步程序包裹在⼀个Promi⾥⾯,这样做的⽬的其实是想把异步处理程序的结果给Promi,稍后再利⽤Promi提供的接⼝函数(then()或者catch())来对结果进⾏处理。
2: 我们在Promi的executor函数⾥调⽤真正的异步操作函数。
我们在executor函数⾥调⽤fs.readFile( )函数。fs.readFile( )函数本⾝是⼀个异步⾏为,其⽅法的第三个参数为⼀个回调函数,⽤来接收⽂件读取的结果(失败时候的error和成功时候的content)。
3: 把异步程序的结果给Promi
我们在fs.readFile( )的回调函数⾥,在⽂件读取成功时调⽤resolve( )⽅法,失败的时候调⽤reject( )⽅法,把成功或者失败的结果通过2个函数的参数传⼊,为Promi在fulfilled或者rejected两种状态时提供数据。
四:编写Promi结果处理程序
蓬莱阁
前⾯我们已经了解到了怎么把⼀个异步处理事件包裹在⼀个Promi⾥⾯,并且通过resolve()和reject()把异步处理事件的结果传递的过程。终于来到了最后⼀步:使⽤结果数据(对⽐现实⽣活,你也可以理解为这⼀步叫做:验证承诺)。
Promi提供2个⽅法来处理结果: Promi.prototype.then() 和 Promi.prototype.catch()。我们分别来看⼀下⼆者的功能:
白醋泡鸡蛋的实验
1:Promi.prototype.then()
then()⽅法接收2个函数类⾏的参数:
1: 第⼀个参数为Promi在fulfilled状态(成功状态)时的回调⽅法陪你一起
2: 第⼀个参数为Promi在rejected状态(失败状态)时的回调⽅法
雨后彩虹是光的什么现象
我们以之前的读取⽂件为例⼦,看⼀下then()⽅法的使⽤:
茂兰镇
这两个回调函数的参数也就是之前异步处理的结果数据。第⼀个函数的参数对应resolve()的参数content,第⼆个回调函数对应reject()的参数error。这样我们也就能在这2个回调函数⾥⾯拿到数据,从⽽根据你的业务需求编写对应的结果处理程序。
需要说明的是,这两个回调函数参数都不是必须的,并不强制要求你都要处理。下⾯的代码⾥,列觉了某2种结果处理程序,语法上都是合
法的。只是正常的需求下,我们⼀般还是需要对成功和失败都要处理。
br
2: Promi.prototype.catch()
catch()⽅法只有⼀个参数:⼀个只处理rejected状态的回调函数。可能会有⼈疑问,then()已经可以同时处理2个状态,为什么还需要catch()⽅法?
原因在于前⾯我们提到的,在then()⽅法⾥,并不强制要求你提供处理rejected的回调函数。Promi有个特性:如果你没有添加rejected 处理函数,那所有的失败会被⾃动忽略。
可能会有些开发者只关⼼成功状态,⽽忘了提供rejected处理函数,从⽽给整个程序埋下隐患,这样会造成很不好的⽤户体验。⽽catch()⽅法就是⼀个明确地处理rejected的⽅法,⽽不像在then()⾥⾯,因为是⾮必须参数⽽让⼈很容易忽略。
背景说了那么多,我们看看catch()怎么⽤:
promi.catch(function (error) {
console.log(error)
})
建设社区其实⽤法很简单,它其实等价于是有reject处理函数的then():
附加价值promi.then(null, function (error) {
console.log(error)
});
没有语法要求⼀个完整的Promi处理程序必须要有catch()⽅法。如果你没有使⽤catch()的习惯,最好总是不要忘记在使⽤then()的时候添加reject处理函数。
或者,如果你偶尔会忘记在then()⾥添加reject处理函数,那么记得使⽤catch()来为你做最安全的保障。
以上,就是关于Promi的基本概念和使⽤。在平常的开发中,Promi的使⽤还是⾮常频繁的,也很好⽤,所以我认为掌握Promi是⼀个必须的功课。
接下来,由浅⼊深 讲解 promi 实现原理
⾸先我们应该知道Promi是通过构造函数的⽅式来创建的(new Promi( executor )),并且为 executor函数 传递参数:
再来说⼀下Promi的三种状态: pending-等待, resolve-成功, reject-失败, 其中最开始为pending状态, 并且⼀旦成功或者失败, Promi 的状态便不会再改变,所以根据这点:

本文发布于:2023-06-28 20:35:07,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1061383.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:结果   函数   状态   回调
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图