长沙前端培训教程知识点:Promise这样理解更简单

2023-06-02 0 341

原副标题:衡阳后端专业培训讲义习题:Promise这种认知更单纯

今天跟大家撷取下衡阳后端专业培训讲义习题:Promise这种认知更单纯。Promise阿宝怎么用?从四个故事情节已经开始吧:

您是一位在有名沉沦城市中探险的盖基。您置身于一家点缀绚丽的卧室中,四面满布了有名的雕塑和浮雕。您发现有四个地下通道依次通往不同的路径,依次是:四个邪恶的地下通道和四个光亮的地下通道。

邪恶的地下通道中充满著了谜样的韵味,您能感受到当中蕴含着的有名力量。您无人知晓它会带您去哪里,但您能感受到当中蕴含的脆弱和未明。再者,光亮的地下通道看上去凉爽宽敞,您能看到高处映照的日光。您能听到许多嘹亮的翩翩起舞,似乎在那个路径上有许多人在庆祝。

现在,您需要在这四个地下通道之间作出优先选择。您会优先选择哪四个地下通道呢?您的优先选择Sonbhadra影响您接下去的历险之旅。

先来介绍两个单字,两个Promise的名词

Promise的四个状况:pending(等候状况)、fulfilled(已获得成功状况)和 rejected(已失利状况)

Promise的四个常见反弹表达式(咱说的是常见):

示例化第一类时传至的反弹表达式 then方式的传至的四个反弹表达式 catch方式传至的四个反弹表达式

以工作台为例,继续深入细致介绍Promise

已经开始写工作台,此时Promise状况为pending,我们能认知为初始状况,也能认知为业务处理中。

工作台完成情形有两种,一类是完稿了,一类是被狗吃了,不论何种情形,必须要告诉同学,获得成功了就透过resolve地下通道存贮统计数据,与此同时会更动状况为获得成功fulfilled;失利了就透过reject地下通道存贮统计数据,与此同时修正状况为rejected。

单纯来几段标识符看看

const p = new Promise(function (resolve, reject) {

resolve(透过获得成功地下通道存储统计数据)

})

//…如果不使用then,提取,则统计数据一直存贮在p第一类中

//提取结果

p.then(function (val) {

console.log(val)

})

这些写法都是固定的,建议使用promise之前一定要充分介绍反弹表达式。咱们再升级一下,写工作台用了5秒钟。

const p1 = new Promise(function (resolve, reject) {

//写工作台用了5秒钟,5秒钟之后,把获得成功的工作台存贮到resolve地下通道中

setTimeout(() => {

resolve(这是工作台)

}, 5000)

})

//上面标识符中调用了resolve的时候,then里面的反弹表达式才会触发,这里有个时间差或者时空差的感觉

p1.then(function (val) {

console.log(val)

})

再升级一下,这工作台他也有被狗吃了的时候,我们假定5秒钟之外就被狗吃了,5秒钟之内就是完成的

const p2 = new Promise(function (resolve, reject) {

//生成四个1~6秒之间的随机数

const time = Math.random() * 4000 + 2000

setTimeout(() => {

if (time <= 5000) {

resolve(获得成功交工作台啦)

} else {

reject(`工作台被狗吃了,耗费了${time秒}`)

}

}, time)

})

//获得成功使用then来接,失利了怎么拿到参数呢?

//用then的第二个参数来拿失利的参数

p2.then(function (val) {

console.log(val)

}, function (err) {

console.log(估计是被狗吃了, err)

})

除了then的第二个参数能拿到失利的结果,还能透过catch方式拿到结果,一会再讨论这两种用法的区别,先看catch的用法,注意这里需要连用

p2.then(function (val) {

console.log(val)

}).catch((reason) => {

//输出失利原因,大概率是被狗吃了

console.log(估计是被狗吃了, reason)

})

再看一类常见的连用的写法

new Promise(function (resolve, reject) {

//生成四个1~6秒之间的随机数

const time = Math.random() * 4000 + 2000

setTimeout(() => {

if (time <= 5000) {

resolve(获得成功交工作台啦)

} else {

reject(`工作台被狗吃了,耗费了${time}秒`)

}

}, time)

}).then(function (val) {

console.log(val)

}).catch((reason) => {

//输出失利原因,大概率是被狗吃了

console.log(估计是被狗吃了, reason)

})

许多需注意的地方

resolve和reject只是四个形参的名字,对应实际的值是promise内部的表达式,调用这四个其实调用的就是promise内部的某个表达式而已,这个名字能随便去改

new Promise(function (ok, fail) {

//此时此刻形参叫ok,但实际代表的是promise内部表达式

ok(ojbk)

}).then((res) => {

//promise内部会存储统计数据,传给res这个变量,此时res 值就是ojbk

console.log(res)

})

例如new Promise(构造器的参数是四个表达式),这个表达式会同步执行,标识符执行到这里的时候就会立即执行。

Promise透过构造表达式同步执行,执行结果调用promise的内部表达式存储,通常叫resolve和reject,四个是获得成功时存储存储使用的地下通道,另四个是失利时存储的地下通道,不论存储到哪个地下通道中,都是写标识符的人去定义的

then有四个参数,分别是四个表达式类型的参数,第四个参数是在调用resolve时会触发,第二个参数是在调用reject时触发

catch方式能替代then的第二个参数,拿到reject结果

附赠then第二个参数和catch的区别

在then的第四个参数里面的标识符,如果出现异常的时候,不用手动的try…catch,透过promise示例第一类的.catch能捕获then内出现的异常,但注意,catch不会捕获构造表达式代码中的错误,来看例子

new Promise(function (ok, fail) {

setTimeout(() => {

//故意5秒后触发k的报错

console.log(k)

}, 5000)

}).then((res) => {

console.log(res)

}).catch(error => {

//这个时候,error是拿不到那个错误的,他不负责console.log(k)所在标识符块中出现的错误

console.log(error)

})

长沙前端培训教程知识点:Promise这样理解更简单

再看四个catch方式能捕获什么地方的错误

长沙前端培训教程知识点:Promise这样理解更简单

大概就是这么个大概使用 Promise 的主要原因是他能解决反弹地狱(反弹嵌套)问题,让标识符变得更优雅,逻辑更清晰。

举四个生活中的例子,早上起床第一件事是要穿拖鞋,第二件事是洗漱,第三件事是穿衣服,第四件事是查看“身手要钱”,第五件事是打开自家房门出去开车上班,每件事都需要串行,每一步与下一步都有关联关系

function foo() {

//1、穿拖鞋已经开始

setTimeout(() => {

//1、2秒后穿拖鞋完成

//2、洗漱已经开始

setTimeout(() => {

//2、2秒后洗漱完成

//3、穿衣服已经开始

setTimeout(()=>{

//3、穿衣服完成

//….不好意思看官,后边还有好两个步骤咱就意思一下,再写就吐了

},2)

}, 2)

}, 2)

}

foo()

就写这几层吧,是不是太恶心了

new Promise((resolve, reject) => {

//1、穿拖鞋

setTimeout(() => {

resolve(穿拖鞋搞定)

}, 2000)

}).then(val => {

//等候穿拖鞋完成后,会调用这个表达式

//2、洗漱

//注意此处!!!,必须使用return 返回四个新的promise来完成链式调用

const p = new Promise((resolve, reject) => {

setTimeout(() => {

resolve(洗漱搞定)

}, 2000)

})

return p

}).then(val => {

//3、穿衣服,此处直接返回,没有使用中间变量

return new Promise((resolve, reject) => {

setTimeout(() => {

resolve(穿衣服搞定)

}, 2000)

})

}).then(val => {

//4、查看“身手要钱”

return new Promise((resolve, reject) => {

setTimeout(() => {

resolve(查看“身手要钱”搞定)

}, 2000)

})

}).then(val => {

//5、开车去上班

// 元气满满的一天

})

Promise其他方式

那么多方式,不讲那么多,race、all什么的网上一抓一大把。说说语法糖await和async的用法

先介绍四个基础规则

await必须修饰的是Promise第一类 await必须在async中使用 await只能接收resolve地下通道的结果,reject结果会导致报错 await修饰的标识符在执行时,标识符是卡住的,类似于alert,这句标识符不执行完,后边的标识符不会向下执行,这也类似于线程同步执行的概念,这也是await有用之处 async修饰的必须是表达式 async修饰后的表达式在执行之后会转为Promise第一类

看几段单纯的标识符

async function foo() {

let k = await new Promise(function (resolve, reject) {

setTimeout(() => {

resolve(qfedu)

}, 2000)

})

console.log(k)

}

foo()

这种用倒是更麻烦,我们把要处理的事黏黏糊糊多弄许多试一试

async function foo() {

let level1 = await new Promise((resolve, reject) => {

//1、穿拖鞋

setTimeout(() => {

resolve(穿拖鞋搞定)

}, 1000)

})

//拿着第一步的结果,去第二步进行操作

let level2 = await new Promise((resolve, reject) => {

setTimeout(() => {

resolve(level1 + 洗漱搞定)

}, 1000)

})

let level3 = await new Promise((resolve, reject) => {

setTimeout(() => {

resolve(level2 + 穿衣服搞定)

}, 1000)

})

let level4 = await new Promise((resolve, reject) => {

setTimeout(() => {

resolve(level3 + 查看“身手要钱”搞定)

}, 1000)

})

console.log(level4 + ,之后开车去上班,元气满满的一天)

}

foo()

输出结果:

这种标识符看上去更加简洁,当然要重点考虑的问题是在整个从上到下的调用过程中,任何四个环节出现问题,都会影响下面的标识符

再来,我们把标识符聚焦到foo()方式调用之前和调用之后

console.log(1)

foo() //这个会输出 穿拖鞋搞定洗漱搞定穿衣服搞定查看“身手要钱”搞定……等

console.log(2)

思考一下,程序输出的顺序

注意,使用async包裹的标识符,属于异步标识符,会在同步标识符之后执行

我们给按钮添加四个点击事件,看点击按钮如何让程序使用await顺序执行

async function foo() {

let level1 = await new Promise((resolve, reject) => {

//1、穿拖鞋

setTimeout(() => {

resolve(穿拖鞋搞定)

}, 1000)

})

//拿着第一步的结果,去第二步进行操作

let level2 = await new Promise((resolve, reject) => {

setTimeout(() => {

resolve(level1 + 洗漱搞定)

}, 1000)

})

let level3 = await new Promise((resolve, reject) => {

setTimeout(() => {

resolve(level2 + 穿衣服搞定)

}, 1000)

})

let level4 = await new Promise((resolve, reject) => {

setTimeout(() => {

resolve(level3 + 查看“身手要钱”搞定)

}, 1000)

})

console.log(level4 + ,之后开车去qfedu上班,元气满满的一天)

}

window.onclick = foo;

//或者是

window.onclick = async function(){

//todo …

//await new Promise…

//await new Promise…

//await new Promise…

//…

}

实际场景中,await 与async通常见来处理ajax请求类标识符,让标识符更简洁,再次强调,await只接收resolve结果,注意reject和error的错误要使用try…catch…处理异常。

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务