前端开发工程师的自我修养:前端开发工程师必须掌握的 Promise(详解)以及在 Vue3 项目中的实战应用

48 篇文章 5 订阅
31 篇文章 12 订阅


在这里插入图片描述

📋前言

在前端编程中(甚至后端有时也是这样),我们在处理一些简短、快速的操作时,例如计算 1 + 1 的结果,往往在主线程中就可以完成。主线程作为一个线程,不能够同时接受多方面的请求。所以,当一个事件没有结束时,界面将无法处理其他请求。为了解决这个问题,JavaScript 中的异步操作函数往往通过回调函数来实现异步任务的结果处理。
在这里插入图片描述
这个时候 Promise 和异步编程就是一个很好的解决方法,接下来我们一起来了解学习下 Promise ,然后通过简单的应用来加深对 Promise 的印象。


🎯关于 promise(用于使用 JavaScript 编写的 Windows 应用商店应用)的内容分享

🔗详细内容地址:关于 promise(用于使用 JavaScript 编写的 Windows 应用商店应用)

当您使用 JavaScript 编写 Windows 应用商店应用时,一旦执行涉及异步 API 的操作时,就会遇到称为 promise 的构造。此外,无需很长时间,为顺序异步操作编写 promise 链就会成为您的一种习惯。

但是,在开发的过程中,您可能会遇到其他使用 promise 的情形,此时您可能无法完全了解具体情况。为 ListView 控件优化项目呈现功能就是一个很好的例子,如在 HTML ListView 优化性能示例中所示。我们将在随后的一篇博文中继续探究这一主题。或者,您也可以了解一下 Josh Williams//build 2012 大会的深入探讨 WinJS 讨论(略有修改)中展示的以下重要代码段:

list.reduce(function callback (prev, item, i) {
    var result = doOperationAsync(item);
    return WinJS.Promise.join({ prev: prev, result: result}).then(function (v) {
        console.log(i + ", item: " + item+ ", " + v.result);
    });
})

该代码段将加入到 promise 来完成并行异步操作,并根据 list 中的命令按顺序提供结果。如果您一看到该代码就可以立即了解其功能,那么您完全可以跳过本博文!否则,让我们来仔细看一下 promise 的真正工作原理,以及其在 WinJS(Windows JavaScript 库)中的表达式,以便了解这些模式类型。

🧩promise 究竟是什么?承诺关系

首先,让我们来了解一下基本情况:promise 实际上无非就是一个代码构造或一个调用约定(如果您愿意)。因此,promise 与异步操作没有内在的关系,它们在这方面非常有用实属巧合!promise 只是一个对象,代表着可能会在将来某一时间可用(或现已可用)的值。这样,promise 的含义就像我们在人际关系中使用该术语一样。如果我说,“我承诺投递给您一打甜甜圈”,则很明显我无需即刻得到这些甜甜圈,而毫无疑问我假定自己可以在将来得到它们。一旦得到甜甜圈,我就会投递给您。

Promise 故暗示着两个代理方之间的关系:承诺发货的发货人与既是承诺的接受方又是收货人的消费者。发货人如何获得这些货物是其自己的事情。同样,消费者可以随意处理承诺和投递的货物。消费者甚至可与其他的消费者分享承诺。

在发货人和消费者之间,也存在着两个关系阶段,创建和履行。全部内容如下图所示。
![在这里插入图片描述](https://img-blog.csdnimg.cn/b8f049dd20fe4a06a9b475dad052d530.png =1200X)
通过该图中显示的流程,我们可以了解到分为两个阶段的关系是 promise 通过异步交货的方式得以履行的原因所在。这个过程的关键部分是一旦消费者认可请求 (即 promise),其可以继续生活 (异步),而不是等待 (同步)。这意味着消费者在等待承诺履行的同时可以做其他的事情,例如响应其他的请求,而这也是异步 API 的初衷。如果已得到货物,情况会怎样?此时,promise 将立即履行,就像是一种同步调用约定。

当然,对于这一关系,我们还要考虑一些额外的东西。在日常生活中,您一定作出过承诺,并且别人也对您作出过承诺。尽管许多承诺已经履行,但许多承诺无法兑现也是事实,例如快递员在为您送披萨的途中发生了交通事故!背弃的承诺是无法改变的事实,无论是在我们的个人生活还是异步编程方面,我们都必须接受。

在承诺关系中,这意味着发货人需要一种表达,“对不起,我无法兑现该承诺”的方式,而消费者也需要一种了解该事实的方式。其次,作为消费者,我们有时会对别人向我们作出的承诺失去耐心!因此,如果发货人可以在履行承诺的过程中跟踪进展情况,消费者也需要一种获得该信息的方式。第三,消费者还可以取消订单,并告知发货人其不再需要该货物。

将这些要求添加到图中之后,我们就会看到完整的关系:
在这里插入图片描述


🎯JavaScript Promise

Promise 是一个 ECMAScript 6 提供的类,目的是更加优雅地书写复杂的异步任务。

由于 PromiseES6 新增加的,所以一些旧的浏览器并不支持,苹果的 Safari 10WindowsEdge 14 版本以上浏览器才开始支持 ES6 特性。以下是 Promise 浏览器支持的情况:
在这里插入图片描述

🧩认识了解 Promise

PromiseJavaScript 中用于处理异步操作的对象,它代表了一个异步操作的最终完成或失败,并可以返回结果或错误信息。在这里插入图片描述
Promise 对象有三个状态:

1. Pending(进行中):初始状态,表示异步操作尚未完成或失败。
2. Fulfilled(已完成):表示异步操作成功完成,并返回了结果。
3. Rejected(已失败):表示异步操作遇到了错误或失败。
在这里插入图片描述
创建 Promise 对象时,需要传入一个执行器函数,该函数接受两个参数 resolvereject。在执行器函数中,通过调用 resolve 函数来将 Promise 状态从 Pending 转变为 Fulfilled ,或者通过调用 reject 函数将其转变为 Rejected 。例如:

const promise = new Promise((resolve, reject) => {
  // 异步操作
  if (/* 异步操作成功 */) {
    resolve(result); // 将状态设置为 Fulfilled,并返回结果
  } else {
    reject(error); // 将状态设置为 Rejected,并返回错误信息
  }
});

Promise 提供了链式调用的方法,例如 thencatchfinally。通过这些方法,可以在 Promise 完成或失败后执行相应的操作。then 方法接收两个回调函数作为参数,第一个回调函数在 PromiseFulfilled 时执行,接收成功的结果作为参数;第二个回调函数在 PromiseRejected 时执行,接收错误信息作为参数。catch 方法用于捕获发生的错误,而 finally 方法则在 Promise 完成后无论成功或失败都会执行。例如:

promise
  .then((result) => {
    // 处理成功的结果
  })
  .catch((error) => {
    // 处理错误信息
  })
  .finally(() => {
    // 执行清理操作
  });

在这里插入图片描述
在这里插入图片描述
下面可以通过这张图看一下 Promise 的执行过程。
在这里插入图片描述
Promise 还提供了一些静态方法,如 Promise.allPromise.race 等。Promise.all 接收一个 Promise 数组作为参数,并返回一个新的 Promise ,只有当所有的 Promise 都成功完成时,这个新的 Promise 才会成功完成,返回结果数组。而 Promise.race 则接收一个 Promise 数组作为参数,并返回一个新的 Promise ,只要其中任何一个 Promise 完成(无论成功还是失败),这个新的 Promise 就会完成。
在这里插入图片描述


🎯在 Vue3 项目中的实战应用

通过上面的内容学习和了解,我们大致搞清楚了什么是 Promise ,接下来我们学以致用,在 Vue3 项目中使用 Promise 做一个示例。

创建一个 Vue 组件,名字叫 AsyncComponent.vue
在这里插入图片描述

<template>
  <div>
    <button @click="startAsyncTask">开始异步任务</button>
    <p v-if="loading">正在加载中...</p>
    <p v-else-if="result">异步任务结果:{{ result }}</p>
    <p v-else>点击按钮开始异步任务</p>
  </div>
</template>

<script setup>
import { ref } from "vue";
const loading = ref(false); // 是否正在加载
const result = ref(null); // 异步任务结果

const startAsyncTask = () => {
  loading.value = true; // 设置加载状态为true

  // 使用Promise包装异步任务
  const asyncTask = new Promise((resolve, reject) => {
    // 模拟异步任务,这里可以是一个API请求、定时器等异步操作
    setTimeout(() => {
      const randomNum = Math.random();
      if (randomNum > 0.5) {
        resolve(`成功,随机数:${randomNum}`);
      } else {
        reject(new Error(`失败,随机数:${randomNum}`));
      }
    }, 2000);
  });

  asyncTask
    .then((res) => {
      result.value = res; // 更新异步任务结果
    })
    .catch((error) => {
      console.error(error); // 处理异步任务失败的情况
    })
    .finally(() => {
      loading.value = false; // 无论成功或失败都将加载状态设置为false
    });
};
</script>

在需要使用异步组件的父组件中引入并使用 AsyncComponent 组件。在这个项目中,我们在 ElementTest2.vue 这个页面引入了 AsyncComponent 组件。
在这里插入图片描述

<template>
  <div>
    <h1>异步组件示例</h1>
    <AsyncComponent />
  </div>
</template>

<script>
import AsyncComponent from "./AsyncComponent.vue";

export default {
  components: {
    AsyncComponent,
  },
};
</script>

🧩运行效果

界面如下。
在这里插入图片描述
点击按钮后,进入加载状态在这里插入图片描述
成功时返回结果如下。
在这里插入图片描述
失败时返回结果如下。
在这里插入图片描述
界面中的 result 之所以没改变,是因为上一次加载成功时把结果赋值给 result 了,但是加载失败的话不会赋值给 result ,而是直接输出到控制台。
在这里插入图片描述


📝最后

到此,这就是文章的全部的内容了。通过这篇文章,我们可以快速了解学习什么是 Promise ,然后通过实战应用学会使用 Promise ,通过使用 Promise ,我们可以更好地管理和组织异步操作,避免了回调地狱,使得代码更具有可读性、可维护性和可扩展性。
在这里插入图片描述

  • 9
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黛琳ghz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值