写给 Java 程序员的前端 Promise 教程

@

  • 1. 为什么需要 Promise
  • 2. Promise
  • 3. then3.1 正常 return3.2 抛出异常3.3 返回 Promise
  • 4. catch
  • 5. finally
  • 6. 其他方法6.1 Promise.all()6.2 Promise.race()6.3 Promise.reject()6.4 Promise.resolve()

小伙伴们知道,松哥最近在录 TienChin 项目,用的 RuoYi-Vue 脚手架,前端关于网络请求的地方,很多都涉及到了 Promise,为了让小伙伴们能更好的理解前端代码,咱们抽空整一篇文章和大家聊聊整个 Promise。

1. 为什么需要 Promise

假设我现在有这样一个需求,用户先去登录,登录成功之后,再去服务端获取用户信息,获取到用户信息之后再去服务端获取前端的动态菜单。一般我们的 Ajax 请求都是异步形式,为了确保上一步操作成功再执行下一个请求,所以最终发出的请求伪代码类似下面这样:

$.ajax({ url:’/login’, data:loginForm, success: function (data) { //登录成功 $.ajax({ url:’/getInfo’, success: function (userInfo) { //获取用户信息成功 $.ajax({ url: ‘/getMenus’, success: function (menus) { //获取菜单成功 } }) } }) }})

为了确保一个异步任务执行完成后,再执行下一个异步任务,我们不得不在回调函数中不停的写下去,上面我举的例子是三个请求嵌套,实际上可能会更多。。。这就是前端所谓的回调地狱。而 Promise 就是来解决回调地狱的。

2. Promise

Promise 从字面上理解,就是承诺,承诺将来在某一个时间会做某一件事。通过 Promise 我们可以将异步任务执行的代码和处理的代码完全分离开。

还是第一小节这个例子,如果我们用 Promise 写,那么方式如下:

function login(resolve, reject) { setTimeout(() => { let number = Math.random(); if (number > 0.5) { resolve(“login success”) } else { reject(“login failed”) } }, 2000);}function getInfo(resolve, reject) { setTimeout(() => { let number = Math.random(); if (number > 0.5) { resolve(“getInfo success”) } else { reject(“getInfo failed”) } }, 2000);}function getMenus(resolve, reject) { setTimeout(() => { let number = Math.random(); if (number > 0.5) { resolve(“getMenus success”) } else { reject(“getMenus failed”) } }, 2000);}new Promise(login).then(data => { console.log(“login:”, data); return new Promise(getInfo);}).then(data => { console.log(“getInfo:”, data); return new Promise(getMenus);}).then(data => { console.log(“getMenus”, data);}).catch(err => { console.log(“err:”, err);})

我们在 Promise 中写异步任务执行的代码,在上面的案例中,松哥通过 setTImeout 方法模拟了一个耗时操作,异步任务执行完毕后,我们调用 resolve 方法返回调用的结果(会进入到下一步的 then 中),也可以调用 reject 方法表示调用失败(会进入到 catch 中)。

3. then

then 中的返回值可以分为三种情况

3.1 正常 return

then 中方法的参数,是上一个 Promise 对象 resolve 的值,一个 Promise 对象可以有多个 then,例如上面案例的登录功能,我们可以一直 then 下去:

function login(resolve, reject) { setTimeout(() => { let number = Math.random(); if (number > 0.5) { resolve(“login success”) } else { reject(“login failed”) } }, 2000);}new Promise(login).then(data => { console.log(“then1:”, data); return data;}).then(data => { console.log(“then2:”, data); return data;}).then(data => { console.log(“then3:”, data);}).catch(err => { console.log(“err:”, err);})

这样可以一直返回,这有点像我们 Java 中的流式编程。

3.2 抛出异常

在 then 中,我们可以对返回结果进行判断,不满足条件也可以直接抛出异常,这样就会进入到最近的 catch 代码块中。如下案例:

function login(resolve, reject) { setTimeout(() => { let number = Math.random(); if (number > 0.5) { resolve(“login success”) } else { reject(“login failed”) } }, 2000);}new Promise(login).then(data => { console.log(“then1:”, data); throw new Error(“出错啦”);}).then(data => { console.log(“then2:”, data); return data;}).then(data => { console.log(“then3:”, data);}).catch(err => { console.log(“err:”, err);})

像上面这段代码,如果进入到第一个 then 中,第一个 then 直接抛出异常,这样直接就进入到 catch 中了,后面的 then 就都不会执行了。

3.3 返回 Promise

第三种情况就是 then 中也可以返回一个 Promise 对象,这个就如同我们第二小节的案例,我这里就不再赘述了。

就说一句,如果 then 中返回的是一个 Promise 对象,那么接下来的 then 其实是这个 Promise 对象的 then,而不是一开始的 Promise 的 then 了。例如如下伪代码:

A.then((data)=>{return B}).then(xxx)

假设 A 和 B 都是 Promise 对象,那么第二个 then 方法是 B 的 then。

好啦,这就是 then 中的三种返回值情况。

4. catch

catch 主要是用来处理异常的情况,两种情况下会进入到 catch 中:

  • Promise 执行的时候通过 reject 返回数据。
  • then 中抛出 Error

出了问题,就由最近的 catch 来处理。

5. finally

最后还有一个 finally 用来兜底,这一套下来感觉有点像我们 Java 中的 try-catch-finally,也就是前面无论如何,最终 finally 中的代码都会执行。不过不同于 Java 中的 finally,Promise 中的 finally 在最终执行完毕后,还可以继续 then。。。前端的蜜汁操作。

6. 其他方法

最后,我们再来看看 Promise 中的其他静态方法。

6.1 Promise.all()

Promise.all() 方法可以接收多个 Promise 对象,并且只返回一个 Promise 实例,这个方法会等所有输入的 Promise 对象的 resolve 方法都返回的时候,或者所有输入的 Promise 对象中有一个 reject 的时候,这个 all 就会执行结束,来看如下一个案例:

const promise1 = Promise.resolve(3);const promise2 = 42;const promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 3000, ‘foo’);});Promise.all([promise1, promise2, promise3]).then((values) => { console.log(values);}).catch(err=>{ console.log(“err”, err);})

当 promise1、promise2 以及 promise3 都执行了 resolve 的时候,就会进入到 then 中,这三个中有任意一个执行了 reject 就会进入到 catch 中。

6.2 Promise.race()

Promise.race() 方法可以接收多个 Promise 对象,一旦迭代器中的某个 Promise resolve 或 reject,返回的 Promise 就会 resolve 或 reject。

和 all 方法的区别在于,race 方法是谁执行的快,就用谁的结果。我们来看如下一段代码:

const promise1 = new Promise((resolve, reject) => { setTimeout(resolve, 500, ‘one’);});const promise2 = new Promise((resolve, reject) => { setTimeout(reject, 600, ‘two’);});Promise.race([promise1, promise2]).then((value) => { console.log(value);});

promise1 执行时间短,promise2 执行时间长,所以最终结果就是 promise1 的结果。

6.3 Promise.reject()

Promise.reject() 方法返回一个带有 reject 原因的 Promise 对象。来看如下一段代码:

function resolved(result) { console.log(‘Resolved’);}function rejected(result) { console.error(result);}Promise.reject(“error”).then(resolved).catch(rejected);

这个执行的时候就会进入到 catch 中。

6.4 Promise.resolve()

Promise.resolve(value) 方法返回一个以给定值解析后的 Promise 对象。

const promise1 = Promise.resolve(3);promise1.then(data=>{ console.log(“data”, data);},err=>{ console.log(“err”, err);})

这个用法比较简单,没啥好说的。

还有一些其他方法我就不一一列举了,感兴趣的小伙伴们可以看看 MDN 上的相关讲解:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise。

好啦,这个东西搞懂了,我们再去看 TienChin 项目的前端,就会非常容易了!

郑重声明:本文内容及图片均整理自互联网,不代表本站立场,版权归原作者所有,如有侵权请联系管理员(admin#wlmqw.com)删除。
(0)
用户投稿
上一篇 2022年8月9日
下一篇 2022年8月9日

相关推荐

  • 简短而有吸引力的标题(100个超强吸引人的标题)

    众所周知,在创作过程中,我们的标题非常重要。 无论是在邮件中、软文中、还是百度竞价的创意,还是图文信息的标题…… 读者第一眼看到的是我们的标题,如果我们的标题没有吸引力的话,那么读…

    2022年11月18日
  • 浅谈大衣哥的儿子,离婚半年以后再次订婚

    今天在抖音上偶然间刷到了这个视频,不得不说有一个好爹真好。想必大家对于朱之文都很熟悉,对他的儿子也很了解,不过多的评价。朱小伟离婚半年,能够再次订婚,不得不说都是他父亲的功劳,对于…

    2022年5月13日
  • 每日优鲜被要求及时公布退费方案

    据北京市消协网站9日消息,针对近日“每日优鲜”无法正常经营引发大量消费者投诉的情况,8月4日下午,市消协约谈北京每日优鲜电子商务有限公司。 市消协副秘书长陈凤翔出席约谈并对企业提出…

    2022年8月10日
  • 从事6年珠宝销售经验告诉你:黄金首饰以旧换新怎么样才不会踩坑

    曾经从事6年的珠宝销售,对于首饰以旧换新的情况,诚心地给出几条中肯的建议,避免不必要的踩坑和后悔!记不住的可以提前收藏起来,以备不时之需! 黄金戴久了想换个款式以旧换新的情况时常都…

    2022年7月29日
  • 低收入的女生,建议你疯狂做这件事

    大家好啊!我是努力攒钱的萍萍姐! 大家都是普通女生。收入不高,那么我们怎样做才能改变自己的收入呢? 下面我分享一下自己的经验吧! 最近大量学习理财知识,当一个人的收入开始停滞不前时…

    2022年8月8日
  • 高危产妇的注意事项

    高危产妇必须要重视产前检查,定期的到医院进行检查,并且要遵照医嘱做好保健工作。如果孕妇年龄较大或是曾经生产过有先天缺陷的孩子,就必须要进行遗传方面的咨询。孕妇不仅要自己学会保健方法…

    2022年8月19日
  • 如果你彩票中了500w你对象看病治疗需要499万你会怎么做?

    题主说了算啊?还是主任说了算?题主说了算的话,我愿意中500w,中了500w,给对象治病花去499万,还剩下一万。(按税后算)这样,治好了对象的病,还剩下一万块钱挺好的。我坚信,题…

    2022年4月3日
  • 冬奥会亮相后,Nike ACG Zoom Gaiadome 将在零售店发售

    早在今年 1 月,Nike ACG就恶意分享了 Zoom Gaiadome FlyEase 的图片,这是一款运动员专属的模型,该品牌表示永远不会看到零售版本。但正如今天所透露的那样…

    2022年8月11日
  • 定位功能 显示好友距离 APP实现

    APP VO 对象 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstr…

    2022年6月19日
  • 抗皱多少岁开始好?常见的抗衰方法有哪些?

    肤质粗糙,无光泽? 细纹出现,开始垮脸? 胶原蛋白每天都在流失 暗沉、细纹、松弛…… 这些你都中招了吗? 抗皱和年龄有关系吗? 抗皱能不能“返老还童”? 时…

    2022年6月4日

联系我们

联系邮箱:admin#wlmqw.com
工作时间:周一至周五,10:30-18:30,节假日休息