什么是promise?初学者怎么理解+ JavaScript promise?

2021-08-24 14:30:07 浏览数 (3904)

如果您是 JavaScript 初学者,您可能很难理解 Promise 的真正含义。我已经阅读了很多关于 Promise 的文章,但问题是这些指南中的许多都没有以相关的方式解释它们。人们不理解 JavaScript 中的 promise 是因为他们并不真正了解它的含义以及它在简单和相关的术语中的行为方式。所以在这篇文章中,我将告诉你一个简短的故事,它解释了 Promise 是什么以及它们是如何工作的。我还将通过一些示例向您展示如何在 JavaScript 中使用 promise。

JavaScript 中的 Promise 是什么?

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

一个年轻人疯狂地进来接受采访。当他的面试即将开始时,他意识到自己忘记了简历。

无赖,对吧?

不过,他并不气馁。幸运的是,他有一个当时还在家里的室友。

他迅速通过电话给他的室友打电话,向他寻求帮助。他恳求他的室友帮忙找他的简历。他的室友答应他一有事情要报告就回短信。

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

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

但如果他没有找到,他应该发回一条失败信息,说明他找不到简历的原因。例如,他可能会将此消息发送给正在面试的朋友:

“抱歉,我找不到你的简历,因为你保险箱的钥匙不见了。”

与此同时,面试按计划继续进行,面试官坚持找到简历的promise,而不是实际的简历。此时,面试官将投递简历的状态设置为 PENDING。

受访者回答了他被问到的所有问题。但归根结底,他的就业仍然取决于他简历的最终状态。

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

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

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

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

promise找到简历并发短信的室友与我们如何在 JavaScript 中定义promise是同义词。代码不会直接或立即返回值。相反,它返回一个promise,它最终将在以后提供该值。

JavaScript 中的 promise 是异步的,这意味着它需要时间来解决或完成。正如搜索申请人的简历需要时间来完成一样。

出于这个原因,面试官决定不坐下来无所事事,所以他们根据投递简历的承诺开始面试候选人。我们正在使用返回简历代替实际简历的promise。

JS 引擎也不会等待什么都不做——它开始执行代码的其他部分,等待 promise 的返回值。

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

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

对于 JavaScript 承诺,我们通过使用回调函数(promise处理程序)来做到这一点。这些函数在嵌套​then()​方法中定义。

要指定要调用的回调,请使用以下两个函数:

  • resolve(value)​:这表示异步任务成功。这将调用​then()​处理程序中的履行回调。
  • reject(error)​:这表示尝试运行异步任务时出错。这将在​then()​处理程序中调用拒绝回调。

如果promise成功,将调用履行回调。如果promise被拒绝,则将调用被拒绝的回调。

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

如何在 JavaScript 中编写 Promise

您可以通过调用​Promise​该类并构造这样的对象在 JavaScript 中定义promise:

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

console.log(myPromise);
在控制台中运行它会返回一个​Promise​对象:

不过,构造一个对象并不是定义 Promise 的唯一方法。您还可以使用内置​Promise​API 来实现相同的功能:

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

console.log(anotherPromise);

虽然第一个代码示例中的 Promise 会等待 3 秒,然后才使用​this is the eventual...​消息实现 Promise,但第二个代码示例中的 Promise 将立即使用相同的消息实现它。

JavaScript 中的拒绝promise

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

这是一个简单而人为的例子,说明了 Promise 是如何被拒绝的:

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

你能想出这个promise被拒绝的原因吗?如果你说“因为a不是假的”,恭喜!

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

如何访问 then()中的先前的Promise结果

当 Promise 最终返回一个值时,您通常希望对该返回值执行一些操作。

例如,如果您正在发出网络请求,您可能希望访问该值并将其显示在用户的页面上。

您可以定义两个回调函数,当promise被实现或被拒绝时,您希望调用它们。这些函数在嵌套​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) }) 

运行此代码将在三秒钟后在控制台中显示完成消息:

请注意,您可以根据需要嵌套任意数量的 promise。每一步都会在上一步之后执行,取上一步的返回值:

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()​方法必须同时接受执行处理程序和拒绝处理程序。这样,如果 Promise 得到满足,则调用第一个,如果 Promise 因错误而被拒绝,则调用第二个。

代码示例 4 和 5 中的 promise 不包含第二个处理程序。因此,假设遇到错误,将没有拒绝处理程序来处理错误。

如果您只想在 中定义一个回调函数(又名完成处理程序)​then()​,那么您将需要​catch()​在 Promise 链的底部嵌套一个方法来捕获任何可能的错误。

如何在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 的角色面试中,您的面试官可能会问一个关于 promise 的问题。

在本文中,我用简单的术语解释了 promise 的含义,并通过一些代码示例展示了它的基本实际用法。

我希望你从这篇文章中得到一些有用的东西。如果你喜欢这样的编程相关教程,可以持续关注W3Cschool