理解 JavaScript 中的 Promise

理解 JavaScript 中的 Promise

什么是承诺?

一个 JavaScript 承诺 功能很像在现实生活中。如果我承诺成为一个更好的程序员,那么实际上只有几个结果是可能的。首先是我每天都在练习,我实际上成为了一个更好的程序员。然后,我可以用我的新技能做任何我喜欢的事情。另一种选择是我懈怠,什么都不学,也不会变得更好。在那种情况下,我将不得不承担后果并应对失败。在 JavaScript 中,可以使用相同的逻辑创建 Promise。

一个 承诺 是一个包含两个独立结果的函数,这些结果在返回值之前依赖于其他变量。在我们现实生活中的例子中,结果是我是否成为一个更好的程序员。那个结果是 解决 或者 被拒绝 基于努力工作或懈怠的变量。

一旦 承诺解决, 回调函数可以使用 a 异步附加到结果 然后 方法。使用 然后 与将回调函数嵌套在其他函数中可以完成的操作相比,可以创建更清晰和简洁的代码。关于一个伟大的事情 承诺 那是 然后 方法可以一个接一个地链接执行,并且没有数量限制 然后 使用的功能。

Mozilla , 以易于理解的格式说明 Promise 是什么:

从本质上讲,promise 是一个返回的对象,您将回调附加到该对象,而不是将回调传递给函数。

让我们看一下下面的代码片段:

 让 p = new Promise((resolve, reject) => {  
 让 a = 1 * 1  
 如果 (a === 1) {  
 解决('成功')  
 } 别的 {  
 拒绝('失败')  
 }  
 })

一个新的变量, p , 被创建并分配给一个新的 承诺 .这里面 承诺 是两个参数, 解决拒绝。 R 解决拒绝 是奠定基础的功能 承诺 .在 - 的里面 承诺 , if 语句确定结果。在这种情况下,它指出, 如果a等于1,则处理函数:resolve。否则,处理函数:reject。 当一个 promise 被执行时,它会返回以下内容:

 承诺 {<fulfilled> : '成功'}  
 [[原型]]:承诺  
 [[PromiseState]]:“实现”  
 [[PromiseResult]]:“成功”

。然后()

因为 一个 事实上,是否等于 1,承诺是 <fulfilled> .一旦一个 Promise 被 <fulfilled> , 一个 然后 语句可以附加到结尾 承诺 这通常用于 获取 API 但也有其他的可能性。 然后 语句包含异步执行的回调函数,并确定应与承诺一起返回什么值。这些回调仅在 Promise 为 <fulfilled> .

“成功”的返回值来自 解决 输入到原始函数中的函数 承诺 作为参数。

 p.then(消息 => {  
 控制台日志(消息)  
 }) // => 成功

。抓住()

那么如果一个 承诺 没有解决?这 抓住 当 Promise 的状态返回为时使用方法 <rejected> 并且是一种优雅的方式来通知用户发生了错误。

下面,我们看到 一个 已被宣布为 1*1 ,等于 1。 如果 语句测试 if 一个 等于 2。因为 一个 已经被声明为 1,Promise 是 <rejected> .

一旦 承诺 被拒绝时,它执行 catch 方法,该方法返回由 拒绝 功能。这可以以多种不同复杂性的方式使用,包括添加一个 然后 到结束 抓住 方法。

 让 p = new Promise((resolve, reject) => {  
 让 a = 1 * 1  
 如果 (a === 2) {  
 解决('成功')  
 } 别的 {  
 reject('这是一条失败的消息!')  
 }  
 }) p.then(消息 => {  
 控制台日志(消息)  
 }).catch(消息 => {  
 控制台日志(消息)  
 }) // => 这是一条失败的消息!

现在, 承诺 都定义好了,我们可以看一个更复杂的函数。首先,让我们回顾一下如何使用回调函数,如果 承诺 不可用,见下文:

 const practicedCodingToday = false  
 常量playedOnPhoneToday = false 功能实践编码(解决,拒绝){  
 如果(!practicedCodingToday){  
 拒绝({  
 message: '确保每天练习几个小时!',  
 名称:《没有练习》  
 })  
 } else if (playedOnPhoneToday) {  
 拒绝({  
 消息:'你似乎分心',  
 名称:“在电话上播放”  
 })  
 } 别的 {  
 解决('保持专注很棒!')  
 }  
 } 函数resolveFunction(消息){  
 console.log(`你做到了!${message}`  
 )} 函数拒绝函数(错误){  
 console.log(`${error.name}: ${error.message}`)  
 } 实践编码(resolveFunction,rejectFunction) // => 没有练习:确保每天练习几个小时!

这段代码本质上是一个 Promise。它需要两个回调函数, 解析函数 拒绝功能 ,作为参数并运行一系列测试以确定最合适的响应, 解决 或者 拒绝 该声明。在这里我们可以看到,因为用户没有练习( practicedCodingToday = false ),拒绝函数被调用并记录失败的语句。使用 Promise 可以使用更简洁的代码创建相同的结果:

 const practicedCodingToday = true  
 常量playedOnPhoneToday = false const practiceCodingPromise = new Promise((resolve, reject) => {  
 如果(!practicedCodingToday){  
 拒绝({  
 message: '确保每天练习几个小时!',  
 名称:《没有练习》  
 })  
 } else if (playedOnPhoneToday) {  
 拒绝({  
 消息:'你似乎分心',  
 名称:“在电话上播放”  
 })  
 } 别的 {  
 解决('保持专注很棒!')  
 }  
 }) 实践编码承诺  
 .then(message => console.log(message))  
 .catch(错误 =>{  
 console.log(`${error.name}: ${error.message}`)  
 }) // => 保持专注很棒!

还有中提琴!您现在已经练习了代码,并且可以看到解析消息已被执行。这使得阅读代码变得非常容易和干净。

承诺方法

到目前为止,似乎 承诺 s 只是组织回调函数的一种干净方式,这部分是正确的。但是,他们还有其他可用于帮助编码的工具。有关可以使用的不同类型方法的简要说明,请参见下文。可以在以下位置找到对这些方法的更深入了解 Mozilla .

.all() 方法

.all() 方法允许同时调用数组(或其他可迭代对象)形式的多个 Promise,并返回所有 Promise 结果的数组。此方法的目的是聚合多个 Promise 的结果,这在需要完成多个异步任务以使代码正确执行时非常有用。

 const practiceCodeDay1 = true  
 const practiceCodeDay2 = true  
 const practiceCodeDay3 = true const practiceDay1 = new Promise((resolve, reject) => {  
 如果(!practiceCodeDay1){  
 reject('你第一天没有练习!')  
 } 别的 {  
 resolve('干得好!你在第一天练习了。')  
 }  
 }) const practiceDay2 = new Promise((resolve, reject) => {  
 如果(!practiceCodeDay2){  
 reject('你没有在第二天练习!')  
 } 别的 {  
 resolve('干得好!你在第二天练习了。')  
 }  
 }) const practiceDay3 = new Promise((resolve, reject) => {  
 如果(!practiceCodeDay3){  
 reject('你第三天没有练习!')  
 } 别的 {  
 resolve('干得好!你在第三天练习了。')  
 }  
 }) Promise.all([practiceDay1, practiceDay2, practiceDay3])  
 .then(messages => console.log(messages))  
 .catch(消息 => console.log(消息)) // => ['干得好!你在第一天练习。',  
 '很好!你在第 2 天练习。',  
 '很好!你在第三天练习了。']

重要的是要注意 .all() 方法只会在所有 Promise 都解决时返回一个数组。否则,当我们将 practiceCodeDay3 更改为 false 时,代码只会返回被拒绝的 Promise,如下所示:

 const practiceCodeDay1 = true  
 const practiceCodeDay2 = true  
 const practiceCodeDay3 = false Promise.all([practiceDay1, practiceDay2, practiceDay3])  
 .then(messages => console.log(messages))  
 .catch(消息 => console.log(消息)) // => 第三天你没有练习!

.race() 方法

很像 承诺.all() 方法, 承诺.race() 方法还输入 Promises 的数组(或可迭代对象)。然而,这里的关键区别在于这将只返回第一个解决的 Promise()。

 Promise.race([practiceDay1, practiceDay2, practiceDay3])  
 .then(messages => console.log(messages))  
 .catch(消息 => console.log(消息)) // => 干得好!你在第一天练习。

.any() 方法

任何 方法接受一个 Promise 数组(或其他可迭代对象),并在数组中的任何一个被解析后立即返回一个 Promise。

 const practiceCodeDay1 = false  
 const practiceCodeDay2 = true  
 const practiceCodeDay3 = true Promise.any([practiceDay1, practiceDay2, practiceDay3])  
 .then(messages => console.log(messages))  
 .catch(消息 => console.log(消息)) // => 干得好!你在第 2 天练习。

Promise.prototype.finally()

finally 方法的工作方式与 然后 或者 抓住 语句,但无论是否 承诺 曾是 满载而归 或者 被拒绝 .这用于当拒绝原因或履行值是什么并不重要并且因此不需要输入参数时。

 const practiceCodeDay1 = true 练习Day1  
 .then(messages => console.log(messages))  
 .then(() => console.log('第二个 .then() 语句'))  
 .then(() => console.log('3rd .then() 语句'))  
 .catch(消息 => console.log(消息))  
 .finally(() => console.log('Completed')) /*  
 很好!你在第一天练习。  
 第二个 .then() 语句  
 第三个 .then() 语句  
 完全的  
 */

结论

一个 承诺 是在创建时未知的值的占位符。它对于复杂的代码非常有用,并且消除了对嵌套回调的一些需求。这 然后 方法被用作一个回调函数,一旦被异步执行 承诺 已经 解决。 catch 方法用于当一个 承诺被拒绝 .这些方法允许以易于阅读和理解的方式编写代码。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/33064/05331308

posted @   哈哈哈来了啊啊啊  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示