稀土掘金 稀土掘金

初学者用的JavaScript承诺(附实例)

如果你是一个JavaScript初学者,你可能正在努力理解什么是真正的承诺。

我最近在Twitter上发表了这个话题,并被大家的反应吓了一跳。所以我决定将其扩展为一个关于JavaScript承诺的入门教程。

我读过很多关于承诺的文章,问题是很多指南都没有以一种亲和的方式解释它们。人们不理解JavaScript中的承诺是什么,是因为他们没有真正了解它是什么,以及它是如何以简单和可联系的方式表现出来的。

所以在这篇文章中,我将告诉你一个小故事,解释什么是承诺,以及它们到底是如何工作的。我还会通过一些例子告诉你如何在你的JavaScript中使用承诺。

什么是JavaScript中的承诺?

想象一下,你正在为你公司的一个职位面试求职者。

一个年轻人急匆匆地来参加面试。当他的面试即将开始时,他意识到他忘记了他的简历。

很遗憾,对吗?

不过,他并没有被吓倒。幸运的是,他有一个室友,当时还在家里。

他迅速通过电话给他的室友打电话,请他帮忙。他恳求他的室友帮助找到他的履历表。他的室友答应一有消息就回短信。

假设简历最终被找到,他就可以回短信了。

"成功,我找到了你的简历!"

但是,如果他没有找到,他应该发回一条失败信息,说明他找不到简历的原因。例如,他可以给正在面试的朋友发这样的信息。

"对不起,我找不到你的简历,因为你的保险箱的钥匙不见了。"

与此同时,面试继续按计划进行,面试官坚守着找到简历的承诺,而不是真正的简历。这时,面试官将简历交付的状态设置为待定。

被面试者回答了所有被问到的问题。但最终,他的就业仍然取决于他简历的最终状态。

他的室友终于回了短信。正如我们之前所讨论的,如果他没有找到简历,他将与你分享这一失败,以及他没有找到简历的原因。

当这种情况发生时,面试将结束,面试者将被拒绝。

另一方面,如果室友找到了简历,他就会高兴地告诉他的朋友他成功了,他就会继续下去,实现他获得工作的希望。

那么,这如何转化为JS代码呢?

室友承诺找到履历表并发回短信,这与我们在JavaScript中定义承诺的方式是一样的。这段代码并不直接或立即返回一个值。相反,它返回一个承诺,即它最终会在以后的时间里提供这个值。

JavaScript中的承诺是异步的,意味着它需要时间来解决或完成。就像搜索求职者的简历需要时间来完成。

出于这个原因,面试官决定不坐以待毙,所以他们根据简历交付的承诺开始对候选人进行面试。我们用返回简历的承诺来代替实际的简历。

JS引擎也不会无所事事地等待 - 它开始执行代码的其他部分,等待承诺的返回值。

消息文本包含简历搜索的状态信息。对于JavaScript Promise来说,这也被称为返回值。

如果消息是 "成功",我们将继续签署候选人,并授予他这个职位。如果失败,我们就着手拒绝他的申请。

对于JavaScript的承诺,我们通过 使用回调函数(承诺处理程序)来实现。这些函数被定义在一个嵌套的then() 方法中。

为了指定调用哪些回调,你可以使用以下两个函数:

  • resolve(value):这表明异步任务是成功的。这将调用then() 处理程序中的履行回调。
  • reject(error):这表明在尝试运行异步任务时出现了错误。这将调用then() 处理程序中的rejection回调。

如果承诺是成功的,将调用履行回调。如果承诺被拒绝,将调用拒绝回调。

一个承诺只是一个尚未完成的异步任务的占位符。当你在脚本中定义一个promise对象时,它不是立即返回一个值,而是返回一个promise。

如何在JavaScript中编写一个诺言

你可以通过调用Promise 类并构造一个像这样的对象来在你的JavaScript中定义一个承诺:

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

console.log(myPromise);

代码示例一

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

不过,构造一个对象并不是你定义承诺的唯一方法。你也可以使用内置的Promise API来实现同样的事情。

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

console.log(anotherPromise);

代码示例二

第一个代码样本中的承诺将等待3秒钟,然后用this is the eventual... 消息来履行承诺,而第二个代码样本中的承诺将立即用同样的消息来履行。

JavaScript中被拒绝的承诺

Promise也可以被拒绝。大多数情况下,拒绝的发生是因为JS在运行异步代码时遇到了某种错误。在这种情况下,它会调用reject() 函数来代替。

下面是一个简单的、伪造的例子,说明承诺如何被拒绝:

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

代码示例三

你能想到这个承诺被拒绝的原因吗?如果你说 "因为a 不是假的",那么恭喜你!在第三个代码示例中的承诺将被拒绝。

第三个代码示例中的承诺在超时三秒后将解析为拒绝,因为(a)? 语句解析为false,这将触发reject

如何用链式承诺then()

当承诺最终返回一个值时,你通常会想对该返回值做些什么。

例如,如果你在做一个网络请求,你可能想访问这个值并在页面上显示给用户。

你可以定义两个回调函数,当一个承诺被实现或被拒绝时,你想被调用。这些函数被定义在一个嵌套的then() 方法里面:

const anotherPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('this is the eventual value the promise will return');
  }, 300);
});

// CONTINUATION
anotherPromise
.then(value => { console.log(value) }) 

代码示例四

运行这段代码将在三秒后在控制台显示履行信息:

请注意,你可以根据你的需要嵌套许多承诺。每一步都将在前一步之后执行,吸收前一步的返回值:

const anotherPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('this is the eventual value the promise will return');
  }, 300);
});

anotherPromise
.then(fulfillFn, rejectFn)
.then(fulfilFn, rejectFn)
.then(value => { console.log(value) })

代码示例五

但我们漏掉了一些重要的东西。

永远记住,一个then() 方法必须同时接受履行处理程序和拒绝处理程序。这样,如果承诺被履行,就会调用第一个处理程序,如果承诺被错误拒绝,就会调用第二个处理程序。

代码样本四和五中的承诺不包括第二个处理程序。所以,假设遇到了错误,就没有拒绝处理程序来处理这个错误。

如果你只打算在then() 中定义一个回调函数(又称履行处理程序),那么你将需要在承诺链的底部嵌套一个catch() 方法来捕捉任何可能的错误。

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

只要在承诺链的任何一点上遇到错误,catch() 方法就会被调用:

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

myPromise
.then(value => { console.log(value) })
.catch(err => { console.log(err) });


代码示例六

由于myPromise 最终会解析为拒绝,嵌套的then() 中定义的函数将被忽略。相反,catch() 中的错误处理程序将被运行,它应该向控制台记录以下错误信息:

结束语

JavaScript承诺是一个非常强大的功能,可以帮助你在JavaScript中运行异步代码。在大多数(如果不是全部)使用JavaScript的职位的面试中,你的面试官可能会问一个关于承诺的问题。

在这篇文章中,我用简单的语言解释了什么是承诺,并通过一些代码实例展示了其基本的实际用法。

我希望你能从这篇文章中得到一些有用的东西。如果你喜欢这样的编程相关教程,你应该看看 我的博客。我定期在那里发表关于软件开发的文章。

谢谢你的阅读,再见。

代做工资流水公司蚌埠工资流水阜阳个人流水打印廊坊房贷收入证明制作汕头薪资流水单多少钱沧州代办签证流水合肥代开工资证明赣州制作贷款流水南宁制作车贷流水蚌埠制作企业流水打印沧州背调银行流水样本常州代做银行流水账单信阳在职证明样本曲靖入职工资流水制作南宁银行流水修改德阳办理房贷工资流水赣州开离职证明包头打印企业对公流水哈尔滨制作银行流水账石家庄办理车贷流水青岛工资流水账单图片遵义对公银行流水代开阜阳个人工资流水 开具信阳贷款流水开具衡阳房贷收入证明代开温州企业银行流水图片遵义自存流水开具烟台企业银行流水报价衡阳代开工资代付流水襄阳贷款流水费用洛阳查签证工资流水香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

代做工资流水公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化