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

news2024/12/30 3:41:50

文章目录

  • 📋前言
  • 🎯关于 promise(用于使用 JavaScript 编写的 Windows 应用商店应用)的内容分享
    • 🧩promise 究竟是什么?承诺关系
  • 🎯JavaScript Promise
    • 🧩认识了解 Promise
  • 🎯在 Vue3 项目中的实战应用
    • 🧩运行效果
  • 📝最后


在这里插入图片描述

📋前言

在前端编程中(甚至后端有时也是这样),我们在处理一些简短、快速的操作时,例如计算 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 故暗示着两个代理方之间的关系:承诺发货的发货人与既是承诺的接受方又是收货人的消费者。发货人如何获得这些货物是其自己的事情。同样,消费者可以随意处理承诺和投递的货物。消费者甚至可与其他的消费者分享承诺。

在发货人和消费者之间,也存在着两个关系阶段,创建和履行。全部内容如下图所示。
在这里插入图片描述
通过该图中显示的流程,我们可以了解到分为两个阶段的关系是 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 ,我们可以更好地管理和组织异步操作,避免了回调地狱,使得代码更具有可读性、可维护性和可扩展性。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/704711.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RK3568平台开发系列讲解(外设篇)HX711调试

🚀返回专栏总目录 文章目录 一、HX711 工作原理二、硬件连接三、驱动四、修改设备树五、测试沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将讲解 HX711 模块调试。 一、HX711 工作原理 该部分由应变片与 HX711 模数转换器组成。应变片上的压力变化引起应…

线程基础、线程之间的共享和协作(初篇)

什么是进程和线程&#xff1f; 进程是操作系统进行资源分配的最小单位。资源包括cpu&#xff0c;内存空间&#xff0c;磁盘io等。同一进程里的多个线程共享该进程的全部系统资源。而进程与进程之间是相互独立的。 线程是cpu调度的最小单位&#xff0c;必须依托于进程而存在。…

高斯金字塔的秘密,尺度空间证明的思考

在构建图像尺度空间的过程中&#xff0c;唯一使用的核函数是高斯核&#xff0c;这一点被T Lindeber在文献《Scale-space theory: a basic tool for analyzing structures at different scales》中证明&#xff0c;高斯核是唯一可以产生多尺度空间的核。 相信大家在使用高斯金字…

Linux多线程与fork()函数

4.1多线程中使用进程复制 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<pthread.h> void* fun(void* arg) {for(int i0;i<5;i){printf("fun run pid%d\n",getpid());sleep(1);} } int m…

基于人工智能与边缘计算Aidlux的鸟类检测驱赶系统(可修改为coco 80类目标检测)

●项目名称 基于人工智能与边缘计算Aidlux的鸟类检测驱赶系统&#xff08;可修改为coco 80类目标检测&#xff09; ●项目简介 本项目在Aidlux上部署鸟类检测驱赶系统&#xff0c;通过视觉技术检测到有鸟类时&#xff0c;会进行提示。并可在源码上修改coco 80类目标检测索引直…

554、Vue 3 学习笔记 -【常用Composition API(二)】 2023.06.30

目录 一、常用Composition API1. 拉开序幕的setup2. ref函数3. reactive函数4. Vue3.0中的响应式原理5. reactive对比ref 二、参考链接 一、常用Composition API 1. 拉开序幕的setup &#xff08;1&#xff09;Vue3.0中一个新的配置项&#xff0c;值为一个函数。 &#xff08…

逍遥自在学C语言 | 常见的预定义宏

前言 在C语言中&#xff0c;预定义宏是由编译器提供的一组特殊标识符&#xff0c;可以在程序中直接使用&#xff0c;无需进行额外的定义。 预定义宏可以提供有关源文件、行号、日期、时间和函数名等信息&#xff0c;对于调试和日志记录非常有用。 一、人物简介 第一位闪亮登…

解决Windows联想笔记本打不开文件,鼠标一直转圈圈的问题

在左下角搜索处输入cmd 然后输入以下命令&#xff1a; DISM.exe /Online /Cleanup-image /Scanhealth 回车 等它运行完 再输入&#xff1a; DISM.exe /Online /Cleanup-image /Restorehealth 回车 等它运行完 再输入&#xff1a; sfc /scannow 等它运行完&#xff0…

Python3,如何实现CPU的并行计算,那还不简单,5种方式,这篇就搞定。

多进程实现CPU并行计算 1、引言2、实战2.1 多进程模式2.1.1 定义2.1.2 multiprocessing2.1.3 模式2.1.4 适用场景2.1.4 代码示例 2.2 执行方法2.2.1 多线程并发执行2.2.2 进程池2.2.3 消息队列2.2.4 内存共享2.2.5 异步IO 3、总结 1、引言 小屌丝&#xff1a;鱼哥&#xff0c;…

神奇的甲方:恰恰是拔高我们最好的机遇!

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

LeetCode 打卡day52--动态规划之子序列问题

一个人的朝圣 — LeetCode打卡第52天 知识总结 Leetcode 300. 最长递增子序列题目说明代码说明 Leetcode 674. 最长连续递增序列题目说明代码说明 Leetcode 718. 最长重复子数组题目说明代码说明 知识总结 今天运用动态规划来解决子序列问题. 子序列 是由数组派生而来的序列&a…

Debezium系列之:深入理解tinyint(n)

Debezium系列之:深入理解tinyint 一、背景二、相关技术博客三、查看表的ddl四、深入理解tinyint(n)五、创建表六、插入数据七、查看topic数据八、总结一、背景 数据库修改了字段类型为tinyint,希望采集的时候能够转化为boolean类型,数据库字段类型如下图所示: 在设置了conv…

机器学习笔记 - Facebook AI Similarity Search(Faiss)简介

一、概述 Facebook AI Similarity Search (Faiss)是高效相似性搜索最受欢迎的轮子之一。给定一组向量,我们可以使用 Faiss 对它们进行索引——然后使用另一个向量(查询向量),我们在索引中搜索最相似的向量。 它包含搜索任何大小的向量集的算法,除非超出RAM的大小。它还包…

Go 语言精进之路——Go语言代码块与作用域理解

文章目录 前言代码块与作用域简介if 条件控制语句的代码块其他控制语句的代码块 前言 如果不深入理解 Go 语言的代码块作用域&#xff0c;程序将产生我们无法理解的行为&#xff0c;比如说在循环中创建 goroutine func, 为什么需要传递参数至 goroutine 内部&#xff0c;否则所…

柠檬精僵尸2023-2024_wb粉丝清道夫比赛博更好用的方法

微博批量移除微博粉丝方法_可视化的界面 多样性选择你要移除清理的粉丝类型 三个按钮就可以搞定了 移除粉丝步骤&#xff1a; 首先打开微博&#xff0c;登陆自己的账号。 找到你想要删除的粉丝&#xff0c;点开他/她的头像&#xff0c;打开他/她的个人主页 如果想要大批量清理…

尚硅谷Docker实战教程-笔记04【Docker镜像】

尚硅谷大数据技术-教程-学习路线-笔记汇总表【课程资料下载】视频地址&#xff1a;尚硅谷Docker实战教程&#xff08;docker教程天花板&#xff09;_哔哩哔哩_bilibili 尚硅谷Docker实战教程-笔记01【理念简介、官网介绍、平台入门图解、平台架构图解】尚硅谷Docker实战教程-笔…

accountId、uid、roleId 游戏中的3种id

1)accountId&#xff1a; // 是一个字符串 这个是字符串&#xff0c;玩家可以输入名字(比如:输入zfoo) 或者 通过微信生成(openid是不变的)。 2)uid&#xff1a;// long 这个是一个很长的,玩家通过http登录授权后&#xff0c;通过web层&#xff0c;由雪花算法根据accountId生成…

【每天40分钟,我们一起用50天刷完 (剑指Offer)】第十一天 11/50

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

Selenium上传文件有多少种方式?不信你有我全

Selenium 封装了现成的文件上传操作。但是随着现代前端框架的发展&#xff0c;文件上传的方式越来越多样。而有一些文件上传的控件&#xff0c;要做自动化控制会更复杂一些&#xff0c;这篇文章主要讨论在复杂情况下&#xff0c;如何通过自动化完成文件上传 1.input 元素上传文…

【FFmpeg实战】AAC编码, 解码

使用命令行进行AAC编码 // PCM的三要素采样率&#xff0c;声道数&#xff0c; 采样格式 ffmpeg -ar 44100 -ac 2 -f s16le -i in.pcm out.aac// -c:a codec:audio 指定的是音频编码 ffmpeg -ar 44100 -ac 2 -f s16le -i in.pcm -c:a libfdk_aac out.aacffmpeg -ar 44100 -ac …