网易首页 > 网易号 > 正文 申请入驻

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

0
分享至

今天跟大家分享下长沙前端培训教程知识点:Promise这样理解更简单。Promise小白怎么用?从一个故事开始吧:

您是一名在古老迷失城市中探险的冒险家。您身处一间装饰华丽的房间中,四周布满了古老的壁画和雕塑。您发现有两个通道分别通向不同的方向,分别是:一个黑暗的通道和一个明亮的通道。

黑暗的通道中充满了神秘的气息,您能感受到其中蕴含的古老力量。您并不知道它会带您去哪里,但您可以感受到其中蕴藏的危险和未知。另一方面,明亮的通道看起来温暖舒适,您可以看到远处照耀的阳光。您能听到一些欢快的音乐声,似乎在那个方向上有一些人在欢庆。

现在,您需要在这两个通道之间做出选择。您会选择哪一个通道呢?您的选择将会影响您接下来的冒险之旅。

先来了解几个单词,几个Promise的术语

Promise的三个状态:pending(等待状态)、fulfilled(已成功状态)和 rejected(已失败状态)

Promise的三个常用回调函数(咱说的是常用):

  • 实例化对象时传入的回调函数
  • then方法的传入的两个回调函数
  • catch方法传入的一个回调函数

以作业为例,继续深入了解Promise

开始写作业,此时Promise状态为pending,我们可以理解为初始状态,也可以理解为业务处理中。

作业完成情况有两种,一种是写完了,一种是被狗吃了,无论哪种情况,必须要告诉老师,成功了就通过resolve通道暂存数据,同时会更改状态为成功fulfilled;失败了就通过reject通道暂存数据,同时修改状态为rejected。

老师如何获取resolve或reject通道传来的数据呢?可以使用Promise对象的.then方法获取resolve或reject的结果,或者使用.catch方法获取reject通道的信息。

简单来一段代码看看

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)
})

再看一个catch方法能捕获什么地方的错误

大概就是这么个大概使用 Promise 的主要原因是他可以解决回调地狱(回调嵌套)问题,让代码变得更优雅,逻辑更清晰。

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

functionfoo() {
//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)
})
returnp
}).then(val => {
//3、穿衣服,此处直接返回,没有使用中间变量
returnnew Promise((resolve, reject) => {
setTimeout(() => {
resolve('穿衣服搞定')
}, 2000)
})
}).then(val => {
//4、查看“身手要钱”
returnnew 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对象

看一段简单的代码

asyncfunctionfoo() {
letk = await new Promise(function(resolve, reject) {
setTimeout(() => {
resolve('qfedu')
}, 2000)
})
console.log(k)
}
foo()

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

asyncfunctionfoo() {
letlevel1 = await new Promise((resolve, reject) => {
//1、穿拖鞋
setTimeout(() => {
resolve('穿拖鞋搞定')
}, 1000)
})
//拿着第一步的结果,去第二步进行操作
letlevel2 = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve(level1 +'洗漱搞定')
}, 1000)
})
letlevel3 = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve(level2 +'穿衣服搞定')
}, 1000)
})
letlevel4 = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve(level3 +'查看“身手要钱”搞定')
}, 1000)
})
console.log(level4 +',之后开车去上班,元气满满的一天')
}
foo()

输出结果:

这样代码看起来更加简洁,当然要重点考虑的问题是在整个从上到下的调用过程中,任何一个环节出现问题,都会影响下面的代码

再来,我们把代码聚焦到foo()方法调用之前和调用之后

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

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

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

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

asyncfunctionfoo() {
letlevel1 = await new Promise((resolve, reject) => {
//1、穿拖鞋
setTimeout(() => {
resolve('穿拖鞋搞定')
}, 1000)
})
//拿着第一步的结果,去第二步进行操作
letlevel2 = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve(level1 +'洗漱搞定')
}, 1000)
})
letlevel3 = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve(level2 +'穿衣服搞定')
}, 1000)
})
letlevel4 = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve(level3 +'查看“身手要钱”搞定')
}, 1000)
})
console.log(level4 +',之后开车去qfedu上班,元气满满的一天')
}
window.onclick = foo;
//或者是
window.onclick = asyncfunction(){
//todo ...
//await new Promise...
//await new Promise...
//await new Promise...
//...
}

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

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
19分6板3助!巩晓彬儿子率队大胜:梦幻脚步+统治攻防,球商真高

19分6板3助!巩晓彬儿子率队大胜:梦幻脚步+统治攻防,球商真高

社会故事回忆录
2024-06-15 10:33:58
广东教育厅建议有条件的地区免费提供校服,家长:不需要免费

广东教育厅建议有条件的地区免费提供校服,家长:不需要免费

小鬼头体育
2024-06-15 17:51:40
缅北女魔头魏榕,帅哥真实自述:把我关进狗笼,我口腔感染了3次

缅北女魔头魏榕,帅哥真实自述:把我关进狗笼,我口腔感染了3次

马尔科故事会
2024-06-15 11:51:34
张镇麟晒新疆旅游照:原谅我的拍照技术 只会直男视角

张镇麟晒新疆旅游照:原谅我的拍照技术 只会直男视角

直播吧
2024-06-15 22:15:04
沙特不跟美国玩儿了?“石油美元协议终结”刷屏,相关搜索量飙升创20年新高!真相是……

沙特不跟美国玩儿了?“石油美元协议终结”刷屏,相关搜索量飙升创20年新高!真相是……

每日经济新闻
2024-06-16 08:14:09
辽宁18岁小伙高考完就跑回老家,晒奶奶做的饭:3年了就馋这一口

辽宁18岁小伙高考完就跑回老家,晒奶奶做的饭:3年了就馋这一口

阿龙美食记
2024-06-15 20:50:59
感受海边野性的美,放纵自己的假期

感受海边野性的美,放纵自己的假期

创意家居精品图鉴
2024-06-08 23:07:36
终于下雨了!今日郑州多区有7级雷暴大风+冰雹

终于下雨了!今日郑州多区有7级雷暴大风+冰雹

鲁中晨报
2024-06-16 09:35:05
原来这么多工作需要保密!网友:儿子跟同学说他在监狱里长大的!

原来这么多工作需要保密!网友:儿子跟同学说他在监狱里长大的!

蜗牛壳里
2024-06-06 15:11:08
老公带我去私人影院体验快乐,结果把我们双方带入深渊,不可收拾

老公带我去私人影院体验快乐,结果把我们双方带入深渊,不可收拾

亲爱的落落
2024-06-05 15:50:28
羞羞的两性知识,啪啪啪中,那些不敢对伴侣说的话

羞羞的两性知识,啪啪啪中,那些不敢对伴侣说的话

水白头
2024-06-15 15:00:17
今年的经济形势有多严峻?身边却出现了许多反常的现象

今年的经济形势有多严峻?身边却出现了许多反常的现象

山丘楼评
2024-06-02 23:30:58
“南涝北旱”之下:有河南农户一个人浇地60亩,有广东居民一周没见到太阳

“南涝北旱”之下:有河南农户一个人浇地60亩,有广东居民一周没见到太阳

红星新闻
2024-06-15 17:47:11
苏纳克吻别梅洛尼,人家想着乔·拜登,并不悄悄,普利亚之会终究要散!

苏纳克吻别梅洛尼,人家想着乔·拜登,并不悄悄,普利亚之会终究要散!

新民晚报
2024-06-15 09:51:22
英格兰遗珠!切尔西20万欧放走16岁穆西亚拉,21岁闪耀欧洲杯✨️

英格兰遗珠!切尔西20万欧放走16岁穆西亚拉,21岁闪耀欧洲杯✨️

直播吧
2024-06-15 19:01:11
独行侠G4大胜追至1-3:7数据证绿凯优势仍巨大 再赢一场概率14.2%

独行侠G4大胜追至1-3:7数据证绿凯优势仍巨大 再赢一场概率14.2%

颜小白的篮球梦
2024-06-15 11:02:50
北美人都被印度人逼疯了!

北美人都被印度人逼疯了!

趣说世界哈
2024-06-14 07:31:27
苹果首次展示卫星短信功能 仅限iPhone 14及以上机型

苹果首次展示卫星短信功能 仅限iPhone 14及以上机型

手机中国
2024-06-14 06:55:20
库里:咱们有四次冠军,为啥单单删掉22年的合照?汤普森:它伤了我们的兄弟情!

库里:咱们有四次冠军,为啥单单删掉22年的合照?汤普森:它伤了我们的兄弟情!

林子说事
2024-06-15 16:38:11
尘埃落定,瓜帅返回!不回老东家,曼城开启B计划,英超大结局

尘埃落定,瓜帅返回!不回老东家,曼城开启B计划,英超大结局

阿泰希特
2024-06-15 21:26:57
2024-06-16 10:50:44
千锋长沙校区
千锋长沙校区
IT云计算行业资料信息分享
627文章数 574关注度
往期回顾 全部

科技要闻

iPhone 16会杀死大模型APP吗?

头条要闻

40余套房屋涉嫌"一房多卖" 有购房者内心积郁因病去世

头条要闻

40余套房屋涉嫌"一房多卖" 有购房者内心积郁因病去世

体育要闻

没人永远年轻 但青春如此无敌还是离谱了些

娱乐要闻

江宏杰秀儿女刺青,不怕刺激福原爱?

财经要闻

打断妻子多根肋骨 上市公司创始人被公诉

汽车要闻

东风奕派eπ008售21.66万元 冰箱彩电都配齐

态度原创

本地
房产
艺术
公开课
军事航空

本地新闻

粽情一夏|海河龙舟赛,竟然成了外国人的大party!

房产要闻

万华对面!海口今年首宗超百亩宅地,重磅挂出!

艺术要闻

穿越时空的艺术:《马可·波罗》AI沉浸影片探索人类文明

公开课

近视只是视力差?小心并发症

军事要闻

普京提停火和谈条件 美防长迅速回应

无障碍浏览 进入关怀版