Promise 到底是什么?看这个小故事

大家好,我是若川,点此加我微信进源码群,一起学习源码。

还可以进《剑指前端offer》交流群。

另外,可以进群免费看下周六Vue专场直播,有尤雨溪分享「Vue3 生态现状以及展望

如果你还是一个 JavaScript 初学者,你可能要纠结一下 Promise 到底是什么。

最近我发了一条动态,描述了这个问题,我被大家的反馈震惊到了。所以我决定写一篇关于 Promise 的教程。

我看过很多关于 Promise 的文章,但大部分教程都没有通过类比的方式解释清楚 Promise 到底是什么。初学者搞不懂 Promise 的根本原因是他们不知道 Promise 是做什么的,以及如何在简单和复杂的场景中使用它。

因此在这篇教程中,我将通过一个小故事来解释什么是 Promise、Promise 是如何工作的。同时我也会通过一些代码示例来说明在 JavaScript 中如何使用 Promise。

什么是 Promise

想象一下,你准备面试某个公司的前端工程师。

你走进面试会场,当面试马上要开始时你发现简历忘带了,这时你怎么办?

你没有气馁。因为你很幸运,你有一个室友。

你马上给室友打电话寻求帮助,恳求室友帮你找到简历。你的室友承诺他一旦找到就立马回你消息。

假设简历被找到,室友给你回复信息:

“太好了,我找到你的简历了!”

但是如果室友没有找到,他就要回复一条失败的信息,并解释他为什么没有找到简历。比如,他可能给正在面试的你发如下信息:

“对不起,我没有找到你的简历,因为你的保险柜钥匙丢了。”

与此同时,面试还要继续。但面试官并没有拿到真实的简历,而是得到一个正在找简历的承诺,同时面试官把该简历的状态设置成进行中(PENDING)

你回答了所有问题。但不幸的是,能否得到这个工作还要依赖你简历的最终状态(FINAL STATUS)

你的室友终于回消息了。正如我们前面讨论过的,如果他没有找到简历,他就需要发一个失败的信息并解释为什么没有找到。

如果是这种情况,面试结束,你被拒绝(Rejected)了。

如果室友找到了简历,他会很高兴的告诉你他找到了,而你将继续面试,并获得(FULFILL)这份工作。

如何把上述过程翻译成 JS 代码

室友承诺找简历并回复信息的过程等同于我们在 JavaScript 中定义一个 Promise。定义 Promise 并不能直接或立即获得返回值,而是返回一个 Promise 对象。这个 Promise 对象在一段时间后会接收返回值。

Promise 对象是异步的,这就意味着程序需要花点时间才能获得结果。这和找简历是一样的,都需要花点时间去找。

基于这个原因,在找的这个时间里,面试官并不是什么都没做,而是基于简历一会儿就找到的承诺,他们依然开始面试候选人。在这个场景里,我们用简历一会儿就找到的承诺替换了真实的简历

同理,JS 引擎也并不是等着什么也不做,而是继续执行后续代码,并将返回的Promise对象状态设置为 Pending

回复信息包含是否找到简历的状态信息。对于Promise对象来说,回复信息被称作返回值。

如果回复信息是 “success”,我们将录取候选人。如果是 “failure”,我们不录取该候选人。

在 Promise 中,我们通过回调函数处理Promise的返回值。这些处理函数定义在then()方法中。

为了指定如何调用回调函数,需要使用以下两个方法:

  • resolve(value): 表明 Promise 任务成功,调用then()的成功回调函数。

  • reject(error): 表明 Promise 任务失败,调用then()的错误回调函数。

如果 Promise 成功,则调用成功回调,如果失败,调用失败回调。

在异步任务完成之前,Promise 只是一个占位符。当你定义了一个 Promise,你并不会立即获得返回值,而是获得一个 Promise 对象。

如何在 JavaScript 中使用 Promise

你可以通过Promise类定义一个 Promise 对象。

const myPromise = new Promise((resolve, reject) => {setTimeout(() => {resolve('this is the eventual value the promise will return');}, 3000);
});console.log(myPromise);

示例 1

在控制台运行将返回一个Promise对象:

bbdd304bcef49a181fe66e0371f81b16.png

除了通过构造函数声明一个 Promise 对象外,还可以使用 Promise 内置的 API 进行声明:

const anotherPromise = Promise.resolve("this is the eventual value the promise will return")console.log(anotherPromise);

示例 2

示例 1 中的 Promise 等待 3s 后获取到成功返回的信息:this is the eventual...,而示例 2 中将立即获取到成功返回的信息。

JavaScript Promise 中的错误处理

Promise 对象也能被_rejected_。大多数时候,rejected  的发生是因为执行异步任务的时候抛出了错误,此时就会调用reject()方法。

下面的示例展示了一个 Promise 对象是如何执行 reject 方法的:

const myPromise = new Promise((resolve, reject) => {let a = false;setTimeout(() => {return (a) ? resolve('a is found!'): reject('sorry, no a');}, 3000);
});

示例 3

你能想到 Promise 被 rejected 的原因吗?如果你的答案是:a的值是 false,那么恭喜你答对了。

在示例 3 中,代码执行 3s 后将调用 reject 方法,因为(a)?表达式的值是 false,所以触发reject方法。

Promise 的链式调用

当 Promise 返回了某个值,通常你都会对返回值进行处理。

比如,你发送了一个网络请求,你期望获取数据并展示在页面上。

你可以定义两个回调函数,当 Promise 返回成功或失败时进行回调。这两个回调函数定义在then()内:

const anotherPromise = new Promise((resolve, reject) => {setTimeout(() => {resolve('this is the eventual value the promise will return');}, 3000);
});// CONTINUATION
anotherPromise
.then(value => { console.log(value) })

示例 4

示例 4 的代码在 3s 后返回成功信息:

5005e8878f6f4801f97121d00902458f.png

原则上你可以无限链式调用,调用链会依次执行,而且前一个 then 的返回值作为参数传入后一个 then。

const anotherPromise = new Promise((resolve, reject) => {setTimeout(() => {resolve('this is the eventual value the promise will return');}, 3000);
});anotherPromise
.then(fulfillFn, rejectFn)
.then(fulfilFn, rejectFn)
.then(value => { console.log(value) })

示例 5

但我们还是遗漏了重要的内容。

要时刻记住,then()方法必须有两个回调函数:第一个参数是成功回调,第二个参数是错误回调。

在示例 4 和示例 5 中都没有传入第二个回调函数。因此,如果代码报错,就没有错误回调捕获错误信息。

如果你执意要在then()中只定义一个回调函数(即成功回调),那么你就需要在 Promise 调用链的末端调用catch()方法捕获任何可能的报错信息。

如何在 JS 中使用catch()方法

在 Promise 调用链上,无论哪个环节报错,catch()方法都会被调用。

const myPromise = new Promise((resolve, reject) => {let a = false;setTimeout(() => {return (a) ? resolve('a is found!'): reject('sorry, no a');}, 3000);
}); myPromise
.then(value => { console.log(value) })
.catch(err => { console.log(err) });

示例 6

因为myPromise最终状态是 rejected,then()方法中的成功回调被忽略。而catch()方法中的错误回调被执行,并在控制台打印如下错误信息:

773facf671bc14547c14141b832b7f30.png

写在最后

JavaScript 中的 Promise 是一个运行异步任务的强大功能。大部分情况下,在前端面试时,面试官都会问一些关于 Promise 的问题。

在这片文章中,我已经解释了 Promise 的简单应用场景,也通过示例的方式展示了基本用法。

希望你能从文章中获取有用的知识。如果你喜欢编程教程,点击查看我的博客。我会经常发布一些有关软件开发的文章。

再次感谢您的阅读,再会。

P/S:  如果你也在学习 JavaScript,我也创建了一个电子书,上面有 50 个关于 js 的主题,而且都是我亲自手绘的哦。


原文链接:https://www.freecodecamp.org/news/what-is-promise-in-javascript-for-beginners/

作者:Kingsley Ubah

译者:wangzili


最后预告福利:扫下方二维码加我微信 ruochuan12,可以拉你进群免费观看10月23日的前端早早聊 Vue 专场直播,大咖云集️,更有「尤雨溪」分享「Vue3 生态现状以及展望」。 另外还可以送50个录播视频和PPT~

3213bf819f0a5e2bb406590a68ebf4ed.png

最近组建了一个湖南人的前端交流群,如果你是湖南人可以加我微信 ruochuan12 私信 湖南 拉你进群。


推荐阅读

1个月,200+人,一起读了4周源码
我历时3年才写了10余篇源码文章,但收获了100w+阅读

老姚浅谈:怎么学JavaScript?

我在阿里招前端,该怎么帮你(可进面试群)

8f46b290b066cb3eaa7762ef6c5fc7b7.gif

················· 若川简介 ·················

你好,我是若川,毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列
从2014年起,每年都会写一篇年度总结,已经写了7篇,点击查看年度总结。
同时,最近组织了源码共读活动

a885e1c6dbb7e96c45659ecc72f0ad94.png

识别方二维码加我微信、拉你进源码共读

今日话题

略。欢迎分享、收藏、点赞、在看我的公众号文章~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/275326.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue 团队公开快如闪电的全新脚手架工具,未来将替代 Vue-CLI,才300余行代码,学它!...

1. 前言大家好,我是若川。欢迎关注我的公众号若川视野源码共读活动ruochuan12想学源码,极力推荐之前我写的《学习源码整体架构系列》jQuery、underscore、lodash、vuex、sentry、axios、redux、koa、vue-devtools、vuex4、koa-compose、vue-next-release…

斑马无线打印服务器,如何设置斑马打印机无线WiFi

安装Zebra Setup Utilities.exe,打开软件(没有该软件的可以向客服索要)界面如果是英文请选择options(选项),选择应用程序语言Simplified Chinese(简体中文)点击确定,关闭软件,重新打开,界面就会显示中文。点击相应的打…

Python自然语言处理学习笔记(19):3.3 使用Unicode进行文字处理

3.3 Text Processing with Unicode 使用Unicode进行文字处理 Our programs will often need to deal with different languages, and different character sets. The concept of “plain text” is a fiction(虚构). If you live in the English-speakin…

小程序卡片叠层切换卡片_现在,卡片和清单在哪里?

小程序卡片叠层切换卡片重点 (Top highlight)介绍 (Intro) I was recently tasked to redesign the results of the following filters:我最近受命重新设计以下过滤器的结果: Filtered results for users (creatives) 用户的筛选结果(创意) 2. Filtered results fo…

效率神器!UI 稿智能转换成前端代码

做前端,不搬砖大家好,我是若川。从事前端五年之久,也算见证了前端数次变革,从到DW(Dreamweaver)到H5C3、从JQuery到MVC框架,无数前端大佬在为打造前端完整生态做出努力,由于他们的努…

$.when.apply_When2Meet vs.LettuceMeet:UI和美学方面的案例研究

$.when.apply并非所有计划应用程序都是一样创建的。 (Not all scheduling apps are created equal.) As any college student will tell you, we use When2Meet almost religiously. Between classes, extracurriculars, work, and simply living, When2Meet is the scheduling…

前端不容你亵渎

大家好,我是若川,点此加我微信进源码群,一起学习源码。同时可以进群免费看Vue专场直播,有尤雨溪分享「Vue3 生态现状以及展望」背景最近我在公众号的后台收到一条留言:言语里充满了对前端的不屑和鄙夷,但仔…

利益相关者软件工程_如何向利益相关者解释用户体验的重要性

利益相关者软件工程With the ever increasing popularity of user experience (UX) design there is a growing need for good designers. However, there’s a problem for designers here as well. How can you show the importance of UX to your stakeholders and convince…

云栖大会上,阿里巴巴重磅发布前端知识图谱!

大家好,我是若川,点此加我微信进源码群,一起学习源码。同时可以进群免费看Vue专场直播,有尤雨溪分享「Vue3 生态现状以及展望」阿里巴巴前端知识图谱,由大阿里众多前端技术专家团历经1年时间精心整理,从 初…

Linux下“/”和“~”的区别

在linux中,”/“代表根目录,”~“是代表目录。Linux存储是以挂载的方式,相当于是树状的,源头就是”/“,也就是根目录。 而每个用户都有”家“目录,也就是用户的个人目录,比如root用户的”家“目…

在当今移动互联网时代_谁在提供当今最好的电子邮件体验?

在当今移动互联网时代Hey, a new email service from the makers of Basecamp was recently launched. The Verge calls it a “genuinely original take on messaging”, and it indeed features some refreshing ideas for the sometimes painful exercise we call inbox man…

React 全新文档上线!

大家好,我是若川,点此加我微信进源码群,一起学习源码。同时可以进群免费看明天的Vue专场直播,有尤雨溪分享「Vue3 生态现状以及展望」,还可以领取50场录播视频和PPT。React 官方文档改版耗时 1 年,今天已完…

网络低俗词_从“低俗小说”中汲取7堂课,以创建有影响力的作品集

网络低俗词重点 (Top highlight)Design portfolios and blockbuster movies had become more and more generic. On the design side, I blame all the portfolio reviews and articles shared by “experienced” designers that repeat the same pieces of advice regardless…

尤雨溪写的100多行的“玩具 vite”,十分有助于理解 vite 原理

1. 前言大家好,我是若川。最近组织了源码共读活动,感兴趣的可以加我微信 ruochuan12想学源码,极力推荐之前我写的《学习源码整体架构系列》jQuery、underscore、lodash、vuex、sentry、axios、redux、koa、vue-devtools、vuex4、koa-compose、…

webflow如何使用_我如何使用Webflow构建辅助项目以帮助设计人员进行连接

webflow如何使用I launched Designer Slack Communities a while ago, aiming to help designers to connect with likeminded people. By sharing my website with the world, I’ve connected with so many designers. The whole experience is a first time for me, so I wa…

重新构想原子化 CSS

感谢印记中文的 QC-L[1] 对本文进行翻译,英文原文: English Version[2]。本文会比往期文章相对长些。这是我个人的一个重大的工具发布,有许多内容我想谈论。如果你能花些时间读完,不胜感激,希望能对你有所帮助 :)推荐访问 https:/…

cv::mat 颜色空间_网站设计基础:负空间

cv::mat 颜色空间Let’s start off by answering this question: What is negative space? It is the “empty” space between and around the subjects of an image. In the context of web design, your “subjects” are the pictures, videos, text, buttons and other e…

[知乎回答] 前端是否要学习 Node.js?

大家好,我是若川。最近组织了源码共读活动,感兴趣的可以加我微信 ruochuan12很多小伙伴都表示收获颇丰。一起学的大多数200行左右的Node.js源码。今天推荐这篇文章。(刚刚在写明天掘金要发的文章,差点忘记今天还没发文。在知乎上看…

shields 徽标_我的徽标素描过程

shields 徽标Sketching is arguably the most important part of my process when it comes to logo design. In the beginning of my design career, I would actually skip this step completely and go right to the computer. I’d find myself getting stuck and then goi…

叮咚,系统检测到 npm 有更新,原理揭秘!

大家好,我是若川。最近组织了源码共读活动,感兴趣的可以加我微信 ruochuan12本文来自V同学投稿的源码共读第六期笔记,写得很有趣。现在已经进行到第十期了。你或许经常看见 npm 更新的提示。npm 更新提示面试官可能也会问你,组件库…