还在为承诺而挣扎吗?你并不孤单!
如何使用承诺?
概括
感谢信
你喜欢做饭吗?我不太清楚,但我喜欢做饭。我通常自己做饭,不过我也不反对有人帮忙。
很多时候,你会遇到这种情况:做饭的时候需要用到什么东西,但那个该死的东西不在你家,你得一边做饭一边请人帮忙拿。与此同时,你还要继续做你的工作!
您可能熟悉这种做事方式 - 在编程语言中 - 我们将其称为异步。
我们在编程中经常会异步执行一些操作。也就是说,我们启动某项任务,甚至在它完成之前,就启动了其他任务。
在 JavaScript 中,我们很大程度上依赖于异步操作——我们目前还没有得到其结果,但稍后会得到。
JavaScript 本身不是异步的,但它支持异步编程。
ES6 引入了一个使处理异步任务更容易的想法:Promises。
承诺是一个对象——最终结果的占位符。
这并不是说我们以前不能做异步操作。我们做到了!
我们要做的就是以某种方式使用回调!当我们需要在操作失败时执行任务时,这样做简直是一种折磨。
Promises 标准化了处理异步事件和回调的方式。
我见过有人在 Promise 上苦苦挣扎。这篇文章旨在帮助大家理解这个令人惊奇的话题。我们将通过现实生活中的例子,努力帮助大家建立起对 Promise 的正确理解。
你越是努力去理解,就越是无法理解任何问题。要想理解,心必须静下来。
— 吉杜·克里希那穆提
因为人们会忘记事情,但会记住故事。
让我们通过这个小故事来理解承诺
我还不是个讲故事的高手!不过,前面的场景包含了所有必要的信息,可以帮助你理解 Promises 的概念。
让我们从中汲取要点并将其应用到 JavaScript 世界。
我们需要一个关于 Promise 的标准描述——没有什么比 MDN 更好的了。
让我们看看这个定义与我们的故事有何关联。
现在这个定义更有意义了!
在 JavaScript 中,Promise只是一个对象。它是一个占位符,用于存储我们现在没有但稍后会得到的值。它确保我们最终能够知道异步操作的结果。
环境并不重要——只有你的生存状态才重要——你选择的是什么样的生存状态?
Promise 本质上是一个对象,对象通常会保留状态。通过修改状态,我们可以在编程中完成许多复杂的任务。
承诺总是处于以下三种状态之一:
- 待定:这是初始状态 — 既未完成也未拒绝。
- fulfilled:表示操作已成功完成。
- 拒绝:表示操作失败。
在深入研究代码之前,让我们通过将基本原理与我们的故事联系起来来建立一个强大的心理模型。
如何使用承诺?
如果我们想在代码中使用promise,那么我们必须首先了解这三个基本概念。
- 如何创建 Promise?
- 如何履行或拒绝承诺?
- 如何运行回调函数——取决于承诺是否被解决或被拒绝。
“启迪人心的不是答案,而是问题。”
— 尤金·尤内斯库
如果你理解了这三件事,处理承诺就会变得轻而易举。
让我们分别看一下每一个。
如何创建Promise* ? *
我们使用new关键字和 promise 构造函数创建一个 promise 的实例。
如何履行或拒绝承诺?
promise 构造函数接受一个函数作为其参数——让我们传入一个箭头函数(但我们可以轻松地使用函数表达式)。
这个函数称为执行器函数,它自动接收两个参数resolve
和reject
。
请记住 —解决和拒绝都是函数。
resolve
是一个函数,当调用时,它将承诺的状态从待定更改为已实现。reject
是一个函数,当调用时,它将承诺的状态从待定更改为拒绝
重要的是要记住,您不能直接改变承诺的状态 - 您可以调用resolve函数来实现承诺,或者调用 rejection函数来拒绝承诺。
这两个函数通常在异步操作之后调用。
为了简单起见,我们用 来setTimeout()
模拟寻找豆腐所需的时间。我们假设你的朋友出去给你发短信需要五分钟。
我们重构了代码以包含该setTimeout
功能。
如果我们拿到豆腐,我们会resolve
在五分钟后打电话,如果我们拿不到豆腐,我们会reject
在五分钟后打电话。
这基本上就是你履行或拒绝承诺的方式。
如何运行回调函数 — 取决于 Promise 是否被解决或被拒绝。
最后一步是了解如何根据 Promise 的状态变化执行回调函数。记住,回调函数是作为参数传递给另一个函数的函数。
回调函数意味着我们将使用该函数作为另一个函数的参数。
让我们定义两个回调函数onFulfilled
——onFailure
onFulfilled()
如果在异步操作后调用resolve,则要调用的函数
onFailure()
是在异步操作之后调用拒绝时要调用的函数。
理想情况下,回调函数中会有更多的代码,但我们只需登录控制台即可达到目的。
回到我们的类比,如果我们找到了豆腐,那么我们的承诺就完成了——我们要摆好桌子吃饭。如果找不到豆腐,那么我们的承诺就被拒绝了——我们必须开始煮意大利面。
您可能想知道如何使用这两个回调函数?
当我们使用 Promise 构造函数创建一个新的 Promise 时,Promise 对象允许我们访问两种方法 -then()
和catch()
我们可以使用promise.then()
和来调用它promise.catch()
。
这里重要的一点是:
- 如果通过调用函数将 Promise 的状态从 pending 变为 fulfilled
resolve
—— 传递给 function 的函数then()
将自动被调用 - 如果通过调用函数将承诺的状态从待处理更改为拒绝,则
reject
传递给函数的函数catch()
将自动被调用
在我们的例子中,我们需要通过
onFulfilled
功能then()
onFailure
功能catch()
这两个函数都是回调函数,因为它们作为参数传递给其他函数。我反复提醒你这一点,因为我见过很多人害怕“回调”这个词——其实没什么好怕的——它们只是普通的函数而已。
我们的 Promise 代码按预期工作。但仍有改进的空间!
如果我们想在解决或拒绝承诺时发送一些数据怎么办?
这样,我们可以在回调函数中利用该值来做其他事情。
好吧,事实证明我们可以通过传递参数来解决这个问题,
- 对于resolve函数,我们将传入一个字符串,内容如下
Got the Tofu
- 对于拒绝函数,我们将传入一个字符串,内容为
Can’t get Tofu
但是我们如何在回调函数中访问这些字符串?
嗯,promise 的优点在于它会自动将传递给resolve 的参数作为回调的参数注入,并将传递给rejection 的onFulfilled
参数作为回调的参数注入。onFailure
您可以看到,我已经将参数包含在这两个回调中,并简单地将它们记录到控制台。
Got the Tofu Set up the table
现在,我们将看到承诺履行时的输出,或者如果出现错误并因此被拒绝时的输出Can't get Tofu Cook pasta.
使用承诺的一个很好的例子是从服务器获取数据;我们承诺最终会获得数据,但总是有可能发生问题。
在实际情况中,情况会有所不同。
您的结果将是:
- 一个对象(JSON)
- 一个数组,
- 或异步操作返回的任何其他数据类型。
本质上,这就是 JavaScript 中 Promise 的基本原理。还有一些细节,我们将在下一篇文章中了解。
“承诺意味着一切,但一旦违背,道歉就毫无意义了”
- 匿名的
概括
- 承诺是一个对象——最终结果的占位符。
- 过去我们使用回调来执行异步操作
- 使用回调很麻烦,尤其是当您需要进行错误处理时。
- Promises 标准化了处理异步事件和回调的方式。
- 承诺始终处于以下三种状态之一:待定(第一种)、已实现或已拒绝。
- 操作已完成并标记为已完成。操作被拒绝,即失败。
- 我们使用new关键字和 promise 构造函数创建一个 promise 。
- 您不能直接改变承诺的状态——您可以调用resolve函数来实现承诺,或者调用 rejection函数来拒绝承诺。
- 我们学习了如何创建 Promise、如何履行或拒绝 Promise、如何运行回调函数(取决于 Promise 是否被解决或拒绝)。
感谢信
我想借此最后一次机会向您表示感谢。
谢谢你来看我!如果没有像你这样的人一直关注我,并勇敢地阅读我的帖子,我不可能取得今天的成就。
希望您能关注我未来的博客文章,并持续关注,因为我认为我们这里有一些很棒的内容。也希望在未来的岁月里,我能在您的职业生涯中为您提供帮助!
下次再见。再见!
文章来源:https://dev.to/polymathsomnath/struggling-with-promises-you-are-not-alone-530g