如何使用 JavaScript Promise – 回调、异步等待和 Promise 方法解释

在本教程中,您将学习有关在 JavaScript 中使用 Promise 和 async/await 所需了解的所有内容。

那么让我们开始吧。

为什么在 JavaScript 中使用 Promise?

ES6 引入了 Promise 作为原生实现。在 ES6 之前,我们使用回调来处理异步操作。

让我们了解什么是回调以及 Promise 解决了哪些与回调相关的问题。

假设我们有一个帖子列表及其各自的评论,如下所示:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> posts <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#999999">[</span>
  <span style="color:#999999">{</span> <span style="color:#990055">post_id</span><span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">:</span></span> <span style="color:#990055">1</span><span style="color:#999999">,</span> <span style="color:#990055">post_title</span><span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">:</span></span> <span style="color:#669900">'First Post'</span> <span style="color:#999999">}</span><span style="color:#999999">,</span>
  <span style="color:#999999">{</span> <span style="color:#990055">post_id</span><span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">:</span></span> <span style="color:#990055">2</span><span style="color:#999999">,</span> <span style="color:#990055">post_title</span><span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">:</span></span> <span style="color:#669900">'Second Post'</span> <span style="color:#999999">}</span><span style="color:#999999">,</span>
  <span style="color:#999999">{</span> <span style="color:#990055">post_id</span><span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">:</span></span> <span style="color:#990055">3</span><span style="color:#999999">,</span> <span style="color:#990055">post_title</span><span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">:</span></span> <span style="color:#669900">'Third Post'</span> <span style="color:#999999">}</span><span style="color:#999999">,</span>
<span style="color:#999999">]</span><span style="color:#999999">;</span>

<span style="color:#0077aa">const</span> comments <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#999999">[</span>
  <span style="color:#999999">{</span> <span style="color:#990055">post_id</span><span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">:</span></span> <span style="color:#990055">2</span><span style="color:#999999">,</span> <span style="color:#990055">comment</span><span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">:</span></span> <span style="color:#669900">'Great!'</span><span style="color:#999999">}</span><span style="color:#999999">,</span>
  <span style="color:#999999">{</span> <span style="color:#990055">post_id</span><span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">:</span></span> <span style="color:#990055">2</span><span style="color:#999999">,</span> <span style="color:#990055">comment</span><span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">:</span></span> <span style="color:#669900">'Nice Post!'</span><span style="color:#999999">}</span><span style="color:#999999">,</span>
  <span style="color:#999999">{</span> <span style="color:#990055">post_id</span><span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">:</span></span> <span style="color:#990055">3</span><span style="color:#999999">,</span> <span style="color:#990055">comment</span><span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">:</span></span> <span style="color:#669900">'Awesome Post!'</span><span style="color:#999999">}</span><span style="color:#999999">,</span>
<span style="color:#999999">]</span><span style="color:#999999">;</span></code></span>

现在,我们将编写一个函数,通过传递帖子 ID 来获取帖子。如果找到该帖子,我们将检索与该帖子相关的评论。

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> <span style="color:#dd4a68">getPost</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#999999">(</span>id<span style="color:#999999">,</span> callback<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
 <span style="color:#0077aa">const</span> post <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> posts<span style="color:#999999">.</span><span style="color:#dd4a68">find</span><span style="color:#999999">(</span> post <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> post<span style="color:#999999">.</span>post_id <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">===</span></span> id<span style="color:#999999">)</span><span style="color:#999999">;</span>
 <span style="color:#0077aa">if</span><span style="color:#999999">(</span>post<span style="color:#999999">)</span> <span style="color:#999999">{</span>
   <span style="color:#dd4a68">callback</span><span style="color:#999999">(</span><span style="color:#0077aa">null</span><span style="color:#999999">,</span> post<span style="color:#999999">)</span><span style="color:#999999">;</span>
 <span style="color:#999999">}</span> <span style="color:#0077aa">else</span> <span style="color:#999999">{</span>
   <span style="color:#dd4a68">callback</span><span style="color:#999999">(</span><span style="color:#669900">"No such post found"</span><span style="color:#999999">,</span> <span style="color:#0077aa">undefined</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
 <span style="color:#999999">}</span>
<span style="color:#999999">}</span><span style="color:#999999">;</span>

<span style="color:#0077aa">const</span> <span style="color:#dd4a68">getComments</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#999999">(</span>post_id<span style="color:#999999">,</span> callback<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
 <span style="color:#0077aa">const</span> result <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> comments<span style="color:#999999">.</span><span style="color:#dd4a68">filter</span><span style="color:#999999">(</span> comment <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> comment<span style="color:#999999">.</span>post_id <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">===</span></span> post_id<span style="color:#999999">)</span><span style="color:#999999">;</span>
 <span style="color:#0077aa">if</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="color:#999999">{</span>
   <span style="color:#dd4a68">callback</span><span style="color:#999999">(</span><span style="color:#0077aa">null</span><span style="color:#999999">,</span> result<span style="color:#999999">)</span><span style="color:#999999">;</span>
 <span style="color:#999999">}</span> <span style="color:#0077aa">else</span> <span style="color:#999999">{</span>
   <span style="color:#dd4a68">callback</span><span style="color:#999999">(</span><span style="color:#669900">"No comments found"</span><span style="color:#999999">,</span> <span style="color:#0077aa">undefined</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
 <span style="color:#999999">}</span>
<span style="color:#999999">}</span></code></span>

在上面的getPost函数中getComments,如果出现错误,我们会将其作为第一个参数传递。但是如果我们得到结果,我们将调用回调函数并将结果作为第二个参数传递给它。

如果您熟悉 Node.js,那么您就会知道这是每个 Node.js 回调函数中使用的非常常见的模式。

现在让我们使用这些函数:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#dd4a68">getPost</span><span style="color:#999999">(</span><span style="color:#990055">2</span><span style="color:#999999">,</span> <span style="color:#999999">(</span>error<span style="color:#999999">,</span> post<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
    <span style="color:#0077aa">if</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="color:#999999">{</span>
     <span style="color:#0077aa">return</span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span><span style="color:#999999">;</span>
    <span style="color:#999999">}</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'Post:'</span><span style="color:#999999">,</span> post<span style="color:#999999">)</span><span style="color:#999999">;</span>
    <span style="color:#dd4a68">getComments</span><span style="color:#999999">(</span>post<span style="color:#999999">.</span>post_id<span style="color:#999999">,</span> <span style="color:#999999">(</span>error<span style="color:#999999">,</span> comments<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
        <span style="color:#0077aa">if</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="color:#999999">{</span>
          <span style="color:#0077aa">return</span> console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span><span style="color:#999999">;</span>
        <span style="color:#999999">}</span>
        console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'Comments:'</span><span style="color:#999999">,</span> comments<span style="color:#999999">)</span><span style="color:#999999">;</span>
    <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>

执行上述代码后,您将看到以下输出:

帖子

 调用 getPost 和 getComments 函数的结果

这是一个CodePen 演示

 正如您所看到的,我们将getComments函数嵌套在getPost回调中。

现在想象一下,如果我们也想找到这些评论的点赞。这也会嵌套在getComments回调中,从而创建更多嵌套。这最终会让代码变得难以理解。

这种回调嵌套称为回调地狱。

您可以看到错误处理条件也在代码中重复,这会创建重复的代码 - 这不好。

因此,为了解决这个问题并允许异步操作,引入了 Promise。

JavaScript 中的 Promise 是什么?

Promise 是 JavaScript 最重要的部分之一,但它们可能会令人困惑且难以理解。许多新开发人员以及经验丰富的开发人员都很难完全掌握它们。

那么什么是承诺呢?Promise 代表一个异步操作,其结果将在将来出现。

在 ES6 之前,没有办法等待某些东西来执行某些操作。例如,当我们想要进行API调用时,没有办法等到结果返回。

为此,我们曾经使用 JQuery 或 Ajax 等外部库,它们有自己的 Promise 实现。但 Promise 没有 JavaScript 实现。

但后来在 ES6 中添加了 Promise 作为原生实现。现在,使用 ES6 中的 Promise,我们可以自己进行 API 调用,并等待它完成后再执行某些操作。

如何创建承诺

要创建 Promise,我们需要使用Promise如下的构造函数:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> promise <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>

构造Promise函数将函数作为参数,该函数在内部接收resolvereject作为参数。

和参数实际上是我们可以根据异步操作的结果调用的函数resolvereject

APromise可以经历三种状态:

  • 待办的
  • 实现了
  • 拒绝

当我们创建一个承诺时,它处于待处理状态。当我们调用该resolve函数时,它会进入已完成状态,如果我们调用reject它,它将进入拒绝状态。

为了模拟长时间运行或异步操作,我们将使用该setTimeout函数。

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> promise <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 <span style="color:#dd4a68">setTimeout</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
  <span style="color:#0077aa">const</span> sum <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#990055">4</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">+</span></span> <span style="color:#990055">5</span><span style="color:#999999">;</span>
  <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span>sum<span style="color:#999999">)</span><span style="color:#999999">;</span>
 <span style="color:#999999">}</span><span style="color:#999999">,</span> <span style="color:#990055">2000</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
</code></span>

在这里,我们创建了一个承诺,它将在 2000 毫秒(2 秒)超时结束后解析为 和 的总和45

为了获得成功执行 Promise 的结果,我们需要使用.then如下方式注册一个回调处理程序:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> promise <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 <span style="color:#dd4a68">setTimeout</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
  <span style="color:#0077aa">const</span> sum <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#990055">4</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">+</span></span> <span style="color:#990055">5</span><span style="color:#999999">;</span>
  <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span>sum<span style="color:#999999">)</span><span style="color:#999999">;</span>
 <span style="color:#999999">}</span><span style="color:#999999">,</span> <span style="color:#990055">2000</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>

promise<span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 9</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
</code></span>

因此,每当我们调用 时resolve,promise 都会返回传递给resolve函数的值,我们可以使用.then处理程序收集该值。

如果操作不成功,那么我们reject这样调用该函数:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> promise <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 <span style="color:#dd4a68">setTimeout</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
  <span style="color:#0077aa">const</span> sum <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#990055">4</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">+</span></span> <span style="color:#990055">5</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">+</span></span> <span style="color:#669900">'a'</span><span style="color:#999999">;</span>
  <span style="color:#0077aa">if</span><span style="color:#999999">(</span><span style="color:#dd4a68">isNaN</span><span style="color:#999999">(</span>sum<span style="color:#999999">)</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
    <span style="color:#dd4a68">reject</span><span style="color:#999999">(</span><span style="color:#669900">'Error while calculating sum.'</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span> <span style="color:#0077aa">else</span> <span style="color:#999999">{</span>
    <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span>sum<span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span>
 <span style="color:#999999">}</span><span style="color:#999999">,</span> <span style="color:#990055">2000</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>

promise<span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
</code></span>

在这里,如果sum不是数字,则我们调用reject带有错误消息的函数。否则,我们调用该resolve函数。

如果执行上面的代码,您将看到以下输出:

承诺_fcc

在没有 catch 处理程序的情况下拒绝 Promise 的结果

正如您所看到的,我们收到一条未捕获的错误消息以及我们指定的消息,因为调用该reject函数会引发错误。但我们还没有添加错误处理程序来捕获该错误。

要捕获错误,我们需要使用.catch如下方式注册另一个回调:

<span style="color:var(--gray85)"><code class="language-js">promise<span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#dd4a68">catch</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
</code></span>

您将看到以下输出:

错误捕获

错误捕获

使用 catch 处理程序拒绝承诺的结果

正如您所看到的,我们已经添加了.catch处理程序,因此我们没有收到任何未捕获的错误 - 我们只是将错误记录到控制台。

这也可以避免突然停止您的应用程序。

因此,始终建议将.catch处理程序添加到每个 Promise 中,这样您的应用程序就不会因为错误而停止运行。

何时使用resolve以及reject

让我们举一个 API 调用的例子。

如果您正在进行 API 调用并且 API 调用成功,则可以resolve通过将 API 结果作为参数传递给该函数来调用该函数。

如果 API 不成功,您可以reject通过将任何消息作为参数传递给函数来调用该函数。

因此,为了指示操作成功,我们调用该resolve函数;为了指示操作不成功,我们调用该reject函数。

什么是 Promise Chaining 以及它为什么有用?

Promise 链是一种用于以更有组织性和可读性的方式管理异步操作的技术。

在 Promise 链中,我们可以附加多个.then处理程序,其中前一个.then处理程序的结果会自动传递到下一个.then处理程序。

使用承诺链有助于避免我们之前看到的回调地狱问题。

Promise chaining 还允许我们以更加线性和顺序的方式编写异步代码,这更容易阅读和理解。

另外,当使用 Promise 链时,我们只能.catch在所有处理程序的末尾附加一个处理程序.then。如果任何中间的 Promise 失败,最后一个.catch处理程序将自动执行。

所以我们不需要添加多个.catch处理程序。这消除了多重错误检查,就像我们之前在回调地狱示例中所做的那样。

Promise 链如何工作

我们可以.then向单个 Promise 添加多个处理程序,如下所示:

<span style="color:var(--gray85)"><code class="language-js">promise<span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'first .then handler'</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
 <span style="color:#0077aa">return</span> result<span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'second .then handler'</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
 console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#dd4a68">catch</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
</code></span>

当我们.then添加多个处理程序时,前一个处理程序的返回值.then会自动传递给下一个.then处理程序。

承诺链接

 承诺链的结果

正如您所看到的,添加4 + 5解决了一个承诺,我们在第一个.then处理程序中获得了该总和。在那里,我们打印一条日志语句并将该总和返回到下一个.then处理程序。

在下一个.then处理程序中,我们添加一条日志语句,然后打印从上一个.then处理程序获得的结果。

这种添加多个.then处理程序的方式称为承诺链。

如何在 JavaScript 中延迟 Promise 的执行

很多时候我们不希望 Promise 立即执行。相反,我们希望它延迟到某些操作完成之后。

为了实现这一点,我们可以将 Promise 包装在一个函数中,并从该函数返回该 Promise,如下所示:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">function</span> <span style="color:#dd4a68">createPromise</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
 <span style="color:#0077aa">return</span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="color:#999999">{</span>
  <span style="color:#dd4a68">setTimeout</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
   <span style="color:#0077aa">const</span> sum <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#990055">4</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">+</span></span> <span style="color:#990055">5</span><span style="color:#999999">;</span>
   <span style="color:#0077aa">if</span><span style="color:#999999">(</span><span style="color:#dd4a68">isNaN</span><span style="color:#999999">(</span>sum<span style="color:#999999">)</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
     <span style="color:#dd4a68">reject</span><span style="color:#999999">(</span><span style="color:#669900">'Error while calculating sum.'</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
   <span style="color:#999999">}</span> <span style="color:#0077aa">else</span> <span style="color:#999999">{</span>
    <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span>sum<span style="color:#999999">)</span><span style="color:#999999">;</span>
   <span style="color:#999999">}</span>
  <span style="color:#999999">}</span><span style="color:#999999">,</span> <span style="color:#990055">2000</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
 <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span>
</code></span>

这样,我们就可以在 Promise 中使用函数参数,使函数真正动态化。

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">function</span> <span style="color:#dd4a68">createPromise</span><span style="color:#999999">(</span>a<span style="color:#999999">,</span> b<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 <span style="color:#0077aa">return</span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="color:#999999">{</span>
  <span style="color:#dd4a68">setTimeout</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
   <span style="color:#0077aa">const</span> sum <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> a <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">+</span></span> b<span style="color:#999999">;</span>
   <span style="color:#0077aa">if</span><span style="color:#999999">(</span><span style="color:#dd4a68">isNaN</span><span style="color:#999999">(</span>sum<span style="color:#999999">)</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
     <span style="color:#dd4a68">reject</span><span style="color:#999999">(</span><span style="color:#669900">'Error while calculating sum.'</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
   <span style="color:#999999">}</span> <span style="color:#0077aa">else</span> <span style="color:#999999">{</span>
    <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span>sum<span style="color:#999999">)</span><span style="color:#999999">;</span>
   <span style="color:#999999">}</span>
  <span style="color:#999999">}</span><span style="color:#999999">,</span> <span style="color:#990055">2000</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
 <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span>

<span style="color:#dd4a68">createPromise</span><span style="color:#999999">(</span><span style="color:#990055">1</span><span style="color:#999999">,</span><span style="color:#990055">8</span><span style="color:#999999">)</span>
 <span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>output<span style="color:#999999">)</span> <span style="color:#999999">{</span>
  console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>output<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 9</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>

<span style="color:#708090">// OR</span>

<span style="color:#dd4a68">createPromise</span><span style="color:#999999">(</span><span style="color:#990055">10</span><span style="color:#999999">,</span><span style="color:#990055">24</span><span style="color:#999999">)</span>
 <span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>output<span style="color:#999999">)</span> <span style="color:#999999">{</span>
  console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>output<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// 34</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>

通用函数

通用函数

延迟执行承诺的结果

注意:当我们创建一个 Promise 时,它​​要么被解决,要么被拒绝,但不会同时发生。所以我们不能在同一个 Promise 中resolvereject

此外,我们只能将单个值传递给resolveorreject函数。

如果要将多个值传递给resolve函数,请将其作为对象传递,如下所示:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> promise <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 <span style="color:#dd4a68">setTimeout</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
  <span style="color:#0077aa">const</span> sum <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#990055">4</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">+</span></span> <span style="color:#990055">5</span><span style="color:#999999">;</span>
  <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#999999">{</span>
   <span style="color:#990055">a</span><span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">:</span></span> <span style="color:#990055">4</span><span style="color:#999999">,</span>
   <span style="color:#990055">b</span><span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">:</span></span> <span style="color:#990055">5</span><span style="color:#999999">,</span>
   sum
  <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
 <span style="color:#999999">}</span><span style="color:#999999">,</span> <span style="color:#990055">2000</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>

promise<span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#dd4a68">catch</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
</code></span>

将对象传递给解析函数以返回多个值

如何在 JavaScript 中使用箭头函数

在上述所有代码示例中,我们在创建 Promise 时使用了常规 ES5 函数语法。

但通常的做法是使用箭头函数语法而不是 ES5 函数语法。

那么我们首先来了解一下什么是箭头函数以及如何使用它。

什么是箭头函数?

在 ES6 之前,声明函数的方式主要有两种。

1.函数声明语法:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">function</span> <span style="color:#dd4a68">add</span><span style="color:#999999">(</span>a<span style="color:#999999">,</span> b<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 <span style="color:#0077aa">return</span> a <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">+</span></span> b<span style="color:#999999">;</span>
<span style="color:#999999">}</span></code></span>

2. 函数表达式语法:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> <span style="color:#dd4a68">add</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">function</span><span style="color:#999999">(</span>a<span style="color:#999999">,</span> b<span style="color:#999999">)</span> <span style="color:#999999">{</span>
 <span style="color:#0077aa">return</span> a <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">+</span></span> b<span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">;</span></code></span>

常规函数和箭头函数之间的主要明显区别在于编写函数的语法。

使用箭头函数语法,我们可以像这样编写上面的添加函数:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> <span style="color:#dd4a68">add</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#999999">(</span>a<span style="color:#999999">,</span> b<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
 <span style="color:#0077aa">return</span> a <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">+</span></span> b<span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">;</span></code></span>

除了箭头之外,您可能看不到太多区别。但是如果我们在函数体中有一行代码,我们可以像这样简化上面的箭头函数:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> <span style="color:#dd4a68">add</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#999999">(</span>a<span style="color:#999999">,</span> b<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> a <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">+</span></span> b<span style="color:#999999">;</span></code></span>

这里我们隐式返回 的结果,因此如果只有一条语句,a + b则不需要关键字。return

因此,使用箭头函数将使您的代码变得更短。

如果你想了解箭头函数的其他功能,可以观看这个视频

使用箭头函数,我们可以将前面的代码写成如下所示:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> promise <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
 <span style="color:#dd4a68">setTimeout</span><span style="color:#999999">(</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
  <span style="color:#0077aa">const</span> sum <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#990055">4</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">+</span></span> <span style="color:#990055">5</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">+</span></span> <span style="color:#669900">'a'</span><span style="color:#999999">;</span>
  <span style="color:#0077aa">if</span><span style="color:#999999">(</span><span style="color:#dd4a68">isNaN</span><span style="color:#999999">(</span>sum<span style="color:#999999">)</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
    <span style="color:#dd4a68">reject</span><span style="color:#999999">(</span><span style="color:#669900">'Error while calculating sum.'</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span> <span style="color:#0077aa">else</span> <span style="color:#999999">{</span>
    <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span>sum<span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span>
 <span style="color:#999999">}</span><span style="color:#999999">,</span> <span style="color:#990055">2000</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>

promise<span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
 console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
</code></span>

您可以根据您的喜好和需求使用 ES5 或 ES6 函数语法。

如何在 JavaScript 中使用异步/等待

在本节中,我们将探讨您需要了解的有关 async/await 的所有信息。

Async/await 为开发人员提供了更好的使用 Promise 的方式。

要使用 async/await,您需要创建一个函数,并async使用 ES5 函数声明语法在函数名称前添加关键字,如下所示:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">async</span> <span style="color:#0077aa">function</span> <span style="color:#dd4a68">someFunction</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
  <span style="color:#708090">// function body</span>
<span style="color:#999999">}</span></code></span>

或使用如下函数表达式语法:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> <span style="color:#dd4a68">someFunction</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">async</span> <span style="color:#0077aa">function</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
  <span style="color:#708090">// function body</span>
<span style="color:#999999">}</span><span style="color:#999999">;</span></code></span>

或者使用像这样的箭头函数:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> <span style="color:#dd4a68">someFunction</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">async</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
  <span style="color:#708090">// function body</span>
<span style="color:#999999">}</span><span style="color:#999999">;</span></code></span>

永远记住,当您将 async 关键字添加到函数中时,它总是返回一个承诺。

看看下面的代码:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> <span style="color:#dd4a68">sayHello</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">async</span> <span style="color:#0077aa">function</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
  <span style="color:#0077aa">return</span> <span style="color:#669900">'Hello'</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">;</span>

<span style="color:#dd4a68">sayHello</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>

你认为上面代码的输出会是什么?

调用函数的结果标记为异步

输出是用字符串履行的承诺Hello

所以下面的代码:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> <span style="color:#dd4a68">sayHello</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">async</span> <span style="color:#0077aa">function</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
  <span style="color:#0077aa">return</span> <span style="color:#669900">'Hello'</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">;</span></code></span>

与此相同:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> <span style="color:#dd4a68">sayHello</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">function</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
 <span style="color:#0077aa">return</span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
  <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'Hello'</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
 <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span></code></span>

与此相同:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> <span style="color:#dd4a68">sayHello</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">function</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
  <span style="color:#0077aa">return</span> Promise<span style="color:#999999">.</span><span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'Hello'</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">;</span></code></span>

Promise.resolve('Hello')只是创建解析为 string 的 Promise 的一种较短方法Hello

因此,要获取实际的 string Hello,我们需要添加.then如下处理程序:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#dd4a68">sayHello</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="color:#999999">{</span>
  console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// Hello</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>

使用 .then 处理程序获取异步函数的结果

现在,我们在哪里使用await关键字?

它在声明为 的函数内部使用async。所以await关键字只能在async函数内部使用。

如果您尝试在非异步函数中使用它,您将收到错误。

假设我们有一个返回两个数字的乘积的承诺,如下所示:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">function</span> <span style="color:#dd4a68">getProduct</span><span style="color:#999999">(</span>a<span style="color:#999999">,</span> b<span style="color:#999999">)</span> <span style="color:#999999">{</span>
  <span style="color:#0077aa">return</span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="color:#999999">{</span>
    <span style="color:#dd4a68">setTimeout</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
      <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span>a <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">*</span></span> b<span style="color:#999999">)</span><span style="color:#999999">;</span>
    <span style="color:#999999">}</span><span style="color:#999999">,</span> <span style="color:#990055">1000</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span></code></span>

我们这样使用它:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#dd4a68">getProduct</span><span style="color:#999999">(</span><span style="color:#990055">2</span><span style="color:#999999">,</span> <span style="color:#990055">4</span><span style="color:#999999">)</span>
  <span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="color:#999999">{</span>
    <span style="color:#dd4a68">getProduct</span><span style="color:#999999">(</span>result<span style="color:#999999">,</span> <span style="color:#990055">2</span><span style="color:#999999">)</span>
      <span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#999999">(</span>finalResult<span style="color:#999999">)</span> <span style="color:#999999">{</span>
        console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'final_result'</span><span style="color:#999999">,</span> finalResult<span style="color:#999999">)</span><span style="color:#999999">;</span>
      <span style="color:#999999">}</span><span style="color:#999999">)</span>
      <span style="color:#999999">.</span><span style="color:#dd4a68">catch</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="color:#999999">{</span>
        console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span><span style="color:#999999">;</span>
      <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span>
  <span style="color:#999999">.</span><span style="color:#dd4a68">catch</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="color:#999999">{</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>

2在上面的代码中,我们首先得到和的乘积4。然后我们使用该结果再次相乘2,最后打印结果。

如果执行上面的代码,您将看到最终结果为 16,即 2 * 4 = 8 和 8 * 2 = 16。

嵌套 .then 回调处理程序的结果

.then上面的and代码  .catch乍一看相当复杂,难以理解。

因此使用 async/await 我们可以将上面的代码简化为:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> <span style="color:#dd4a68">printResult</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">async</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
  <span style="color:#0077aa">try</span> <span style="color:#999999">{</span>
    <span style="color:#0077aa">const</span> result <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">await</span> <span style="color:#dd4a68">getProduct</span><span style="color:#999999">(</span><span style="color:#990055">2</span><span style="color:#999999">,</span> <span style="color:#990055">4</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// line 1</span>
    <span style="color:#0077aa">const</span> finalResult <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">await</span> <span style="color:#dd4a68">getProduct</span><span style="color:#999999">(</span>result<span style="color:#999999">,</span> <span style="color:#990055">2</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// line 2</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'final_result'</span><span style="color:#999999">,</span> finalResult<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// line 3</span>
  <span style="color:#999999">}</span> <span style="color:#0077aa">catch</span> <span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="color:#999999">{</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span>
<span style="color:#999999">}</span><span style="color:#999999">;</span>

<span style="color:#dd4a68">printResult</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>

这看起来更干净且易于理解。

在这里,为了使用await关键字,我们用async关键字声明一个函数。然后,为了获取每个 Promise 的结果,我们await在其前面添加关键字。

另请注意,我们在函数内添加了 try/catch。您始终需要在使用的代码周围添加一个 try 块await,以便在 Promise 被拒绝时执行 catch 块。

有一件非常重要的事情你需要记住:上面的 async/await 代码将与我们使用时完全相同.then- 所以下一await行(第 2 行)将不会被执行,直到上一个await调用(第 1 行)成功。

因此,由于getProductsetTimeout 调用,该函数需要 1 秒才能执行,因此第 2 行必须等待 1 秒才能再次执行该getProduct函数。

另外,如果在执行第 1 行时出现错误(由于函数中发生了某些错误getProduct),则第 1 行之后的下一个代码将不会被执行。相反,catch 块将被执行。

现在,如果您比较 Promise Chaining 和 async/await 的代码,您就会看到差异。

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#708090">// code using async/await</span>

<span style="color:#0077aa">const</span> <span style="color:#dd4a68">printResult</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">async</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
  <span style="color:#0077aa">try</span> <span style="color:#999999">{</span>
    <span style="color:#0077aa">const</span> product <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">await</span> <span style="color:#dd4a68">getProduct</span><span style="color:#999999">(</span><span style="color:#990055">2</span><span style="color:#999999">,</span> <span style="color:#990055">4</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// line 1</span>
    <span style="color:#0077aa">const</span> finalResult <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">await</span> <span style="color:#dd4a68">getProduct</span><span style="color:#999999">(</span>product<span style="color:#999999">,</span> <span style="color:#990055">2</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// line 2</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'final_result'</span><span style="color:#999999">,</span> finalResult<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// line 3</span>
  <span style="color:#999999">}</span> <span style="color:#0077aa">catch</span> <span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="color:#999999">{</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span>
<span style="color:#999999">}</span><span style="color:#999999">;</span>

<span style="color:#dd4a68">printResult</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>
<span style="color:var(--gray85)"><code class="language-js"><span style="color:#708090">// code using .then and .catch</span>

<span style="color:#dd4a68">getProduct</span><span style="color:#999999">(</span><span style="color:#990055">2</span><span style="color:#999999">,</span> <span style="color:#990055">4</span><span style="color:#999999">)</span>
  <span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="color:#999999">{</span>
    <span style="color:#dd4a68">getProduct</span><span style="color:#999999">(</span>result<span style="color:#999999">,</span> <span style="color:#990055">2</span><span style="color:#999999">)</span>
      <span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#999999">(</span>finalResult<span style="color:#999999">)</span> <span style="color:#999999">{</span>
        console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'final_result'</span><span style="color:#999999">,</span> finalResult<span style="color:#999999">)</span><span style="color:#999999">;</span>
      <span style="color:#999999">}</span><span style="color:#999999">)</span>
      <span style="color:#999999">.</span><span style="color:#dd4a68">catch</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="color:#999999">{</span>
        console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span><span style="color:#999999">;</span>
      <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span>
  <span style="color:#999999">.</span><span style="color:#dd4a68">catch</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="color:#999999">{</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>

正如您所看到的,与 Promise 链相比,使用 async/await 的代码更加干净且易于理解。

随着嵌套越来越深,使用 Promise 链的代码变得越来越复杂。所以 async/await 只是提供了一种编写相同代码但更清晰的方法。

.catch使用 async/await 还可以减少添加多个处理程序来处理错误的需要。

我们可以通过编写前面的代码来避免上述承诺链中的嵌套:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#dd4a68">getProduct</span><span style="color:#999999">(</span><span style="color:#990055">2</span><span style="color:#999999">,</span> <span style="color:#990055">4</span><span style="color:#999999">)</span>
  <span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="color:#999999">{</span>
    <span style="color:#0077aa">return</span> <span style="color:#dd4a68">getProduct</span><span style="color:#999999">(</span>result<span style="color:#999999">,</span> <span style="color:#990055">2</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span>
  <span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#999999">(</span>finalResult<span style="color:#999999">)</span> <span style="color:#999999">{</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'final_result'</span><span style="color:#999999">,</span> finalResult<span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span>
  <span style="color:#999999">.</span><span style="color:#dd4a68">catch</span><span style="color:#999999">(</span><span style="color:#0077aa">function</span> <span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="color:#999999">{</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>

在这里,我们从第一个.then处理程序返回 的结果getProduct(result, 2)

从前一个.then处理程序返回的任何内容都将传递给下一个.then处理程序。

由于该getProduct函数返回一个承诺,因此我们可以.then再次附加到它并避免需要嵌套.catch处理程序。

但 async/await 语法仍然比 Promise 链接语法看起来更干净、更容易理解。

承诺方法

在本节中,我们将探讨 Promise API 提供的各种方法。

当您想要同时执行多个异步任务且这些任务彼此不依赖时(这可以节省大量时间),所有这些方法都非常有用。

因为如果您一个接一个地执行每个任务,那么您必须等待上一个任务完成才能开始下一个任务。

如果任务彼此不相关,则在执行下一个任务之前等待上一个任务完成是没有意义的。

方法Promise.all_

该方法用于同时执行多个异步任务,而无需等待另一个任务完成。

假设我们有三个 Promise,并且都已成功解决:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> promise1 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'promise1 success'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">const</span> promise2 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'promise2 success'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">const</span> promise3 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'promise3 success'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>

现在,让我们使用该Promise.all方法。

Promise.all需要一组承诺作为其参数。

<span style="color:var(--gray85)"><code class="language-js">Promise<span style="color:#999999">.</span><span style="color:#dd4a68">all</span><span style="color:#999999">(</span><span style="color:#999999">[</span>promise1<span style="color:#999999">,</span> promise2<span style="color:#999999">,</span> promise3<span style="color:#999999">]</span><span style="color:#999999">)</span>
  <span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'resolved'</span><span style="color:#999999">,</span> result<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// resolved ["promise1 success", "promise2 success", "promise3 success"]</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span>
  <span style="color:#999999">.</span><span style="color:#dd4a68">catch</span><span style="color:#999999">(</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'rejected'</span><span style="color:#999999">,</span> error<span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>

当所有承诺都得到解决时,result将是一个包含已解决承诺结果的数组。

现在,如果任何承诺被拒绝怎么办?

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> promise1 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'promise1 success'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">const</span> promise2 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">reject</span><span style="color:#999999">(</span><span style="color:#669900">'promise2 failure'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">const</span> promise3 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'promise3 success'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>

Promise<span style="color:#999999">.</span><span style="color:#dd4a68">all</span><span style="color:#999999">(</span><span style="color:#999999">[</span>promise1<span style="color:#999999">,</span> promise2<span style="color:#999999">,</span> promise3<span style="color:#999999">]</span><span style="color:#999999">)</span>
  <span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'resolved'</span><span style="color:#999999">,</span> result<span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span>
  <span style="color:#999999">.</span><span style="color:#dd4a68">catch</span><span style="color:#999999">(</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'rejected'</span><span style="color:#999999">,</span> error<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// rejected promise2 failure</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>

在上面的代码中,promise2 被拒绝,因此 catch 处理程序将被执行,并且在以下情况下Promise.all

  • 如果其中一个承诺被拒绝,则会error包含失败承诺的错误消息(如我们上面的例子)
  • 如果多个 Promise 被拒绝,则将error是第一个失败的 Promise 的错误消息。

注意:即使中间的 Promise 被拒绝,所有后续的 Promise 也不会停止执行。它们都会被执行——但只有第一个被拒绝的 Promise 值在 catch 块的错误参数中可用。

方法Promise.race_

再次考虑三个已解决的承诺:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> promise1 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'promise1 success'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">const</span> promise2 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'promise2 success'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">const</span> promise3 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'promise3 success'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>

Promise<span style="color:#999999">.</span><span style="color:#dd4a68">race</span><span style="color:#999999">(</span><span style="color:#999999">[</span>promise1<span style="color:#999999">,</span> promise2<span style="color:#999999">,</span> promise3<span style="color:#999999">]</span><span style="color:#999999">)</span>
  <span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'resolved'</span><span style="color:#999999">,</span> result<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// resolved promise1 success</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span>
  <span style="color:#999999">.</span><span style="color:#dd4a68">catch</span><span style="color:#999999">(</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'rejected'</span><span style="color:#999999">,</span> error<span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>

正如您在这里所看到的,一旦第一个 Promise 得到解决,该Promise.race方法就会返回该已解决 Promise 的结果。

现在,看一下下面的代码:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> promise1 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">reject</span><span style="color:#999999">(</span><span style="color:#669900">'promise1 failure'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">const</span> promise2 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'promise2 success'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">const</span> promise3 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'promise3 success'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>

Promise<span style="color:#999999">.</span><span style="color:#dd4a68">race</span><span style="color:#999999">(</span><span style="color:#999999">[</span>promise1<span style="color:#999999">,</span> promise2<span style="color:#999999">,</span> promise3<span style="color:#999999">]</span><span style="color:#999999">)</span>
  <span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'resolved'</span><span style="color:#999999">,</span> result<span style="color:#999999">)</span><span style="color:#999999">;</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span>
  <span style="color:#999999">.</span><span style="color:#dd4a68">catch</span><span style="color:#999999">(</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
    console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'rejected'</span><span style="color:#999999">,</span> error<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#708090">// rejected promise1 failure</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span></code></span>

正如您在这里所看到的,第一个 Promise 本身被拒绝,因此.catch处理程序将被执行。

因此,当我们使用该Promise.race方法时,它将等到第一个承诺得到解决或拒绝,然后:

  • 如果 Promise 链中的第一个 Promise 得到解决,则.then处理程序将被执行,结果将是第一个已解决的 Promise 的结果。
  • 如果 Promise 链中的第一个 Promise 被拒绝,则.catch处理程序将被执行,结果将是第一个失败的 Promise 的结果。
  • 如果多个 Promise 被拒绝,则.catch处理程序将被执行,结果将是第一个失败的 Promise 的结果。

方法Promise.allSettled_

当您想知道每个任务的结果(即使任务被拒绝)时,此方法非常有用。

因为在Promise.allPromise.race中,我们只能得到第一个被拒绝的 Promise 的结果,而无法得到其他成功或失败的 Promise 的结果。

因此,使用Promise.allSettled我们可以获得所有承诺的结果,即使它们失败了。

看看下面的代码:

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> promise1 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'promise1 success'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">const</span> promise2 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'promise2 success'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">const</span> promise3 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'promise3 success'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>

Promise<span style="color:#999999">.</span><span style="color:#dd4a68">allSettled</span><span style="color:#999999">(</span><span style="color:#999999">[</span>promise1<span style="color:#999999">,</span> promise2<span style="color:#999999">,</span> promise3<span style="color:#999999">]</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
  console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'resolved'</span><span style="color:#999999">,</span> result<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>

<span style="color:#708090">/* output from `.then`:
resolved [
  {
    "status": "fulfilled",
    "value": "promise1 success"
  },
  {
    "status": "fulfilled",
    "value": "promise2 success"
  },
  {
    "status": "fulfilled",
    "value": "promise3 success"
  }
]
*/</span></code></span>

正如您所看到的,该Promise.allSettled方法会等待,直到所有 Promise 都得到解决或拒绝,并且resultwill 包含每个 Promise 的结果。

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> promise1 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">reject</span><span style="color:#999999">(</span><span style="color:#669900">'promise1 failure'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">const</span> promise2 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'promise2 success'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">const</span> promise3 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">resolve</span><span style="color:#999999">(</span><span style="color:#669900">'promise3 success'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>

Promise<span style="color:#999999">.</span><span style="color:#dd4a68">allSettled</span><span style="color:#999999">(</span><span style="color:#999999">[</span>promise1<span style="color:#999999">,</span> promise2<span style="color:#999999">,</span> promise3<span style="color:#999999">]</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
  console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'resolved'</span><span style="color:#999999">,</span> result<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>

<span style="color:#708090">/* output from `.then`:
resolved [
  {
    "status": "rejected",
    "reason": "promise1 failure"
  },
  {
    "status": "fulfilled",
    "value": "promise2 success"
  },
  {
    "status": "fulfilled",
    "value": "promise3 success"
  }
]
*/</span></code></span>

在上面的情况下,即使第一个 Promise 被拒绝,我们也会得到处理程序内所有 Promise 的结果.then

<span style="color:var(--gray85)"><code class="language-js"><span style="color:#0077aa">const</span> promise1 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">reject</span><span style="color:#999999">(</span><span style="color:#669900">'promise1 failure'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">const</span> promise2 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">reject</span><span style="color:#999999">(</span><span style="color:#669900">'promise2 failure'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">const</span> promise3 <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=</span></span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">Promise</span><span style="color:#999999">(</span><span style="color:#999999">(</span>resolve<span style="color:#999999">,</span> reject<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#dd4a68">reject</span><span style="color:#999999">(</span><span style="color:#669900">'promise3 failure'</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span>

Promise<span style="color:#999999">.</span><span style="color:#dd4a68">allSettled</span><span style="color:#999999">(</span><span style="color:#999999">[</span>promise1<span style="color:#999999">,</span> promise2<span style="color:#999999">,</span> promise3<span style="color:#999999">]</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#dd4a68">then</span><span style="color:#999999">(</span><span style="color:#999999">(</span>result<span style="color:#999999">)</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">=></span></span> <span style="color:#999999">{</span>
  console<span style="color:#999999">.</span><span style="color:#dd4a68">log</span><span style="color:#999999">(</span><span style="color:#669900">'resolved'</span><span style="color:#999999">,</span> result<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">;</span>

<span style="color:#708090">/* output from `.then`:
 resolved [
  {
    "status": "rejected",
    "reason": "promise1 failure"
  },
  {
    "status": "rejected",
    "reason": "promise2 failure"
  },
  {
    "status": "rejected",
    "reason": "promise3 failure"
  }
] 
*/</span></code></span>

在这里,即使所有的 Promise 都被拒绝,.then处理程序仍然会被执行,并且我们得到每个 Promise 的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值