当前位置: 首页 > news >正文

ES6的promise

Promise是什么

1、Promise是js中的一个原生对象,是一种异步编程的解决方案。可以替换掉传统的回调函数解决方案,将异步操作以同步的流程表达出来。

2、Promise有三种状态:pending(初始化)、fulfilled(成功)、rejected(失败)

可以通过resolve()与reject()改变当前的promise对象的状态

● resolve()使当前promise对象状态改为fulfilled

● reject()使当前promise对象状态改为rejected

● 一般抛出异常也会导致promise对象状态改为rejected

3、相关概念

回调函数:当一个函数作为参数传入另一个函数中,当满足一定条件后该函数才执行,这种函数就称为回调函数。例如我们熟悉的定时器就存在回调函数。

同步任务:同步任务在主线程上排队执行,只有前一个任务执行完毕,才能执行下一个任务。

异步任务:异步任务不进入主线程,而是进入异步队列,前一个任务是否执行完毕不影响下一个任务的执行。

为什么使用Promise

Promise对象提供了简洁的API,使得控制异步操作更加容易。可以很好地解决回调地狱问题

1、回调地狱

为了在异步函数当中顺序执行代码而而不断嵌套调用回调函数,例如以下代码:

setTimeout(() => {console.log('setTimeout1');setTimeout(() => {console.log('setTimeout2');setTimeout(() => {console.log('setTimeout3');}, 1000);}, 2000);
}, 3000);// 分别输出setTimeout1、setTimeout2、setTimeout3

2、Promise链式编程解决回调地狱

getPromise(str, time) {return new Promise((resolve, reject) => {setTimeout(() => {resolve(str)}, time);});
}
const p1 = this.getPromise('setTimeout1', 3000);
const p2 = this.getPromise('setTimeout2', 2000);
const p3 = this.getPromise('setTimeout3', 1000);
p1.then((data1) => {console.log(data1);return p2;
})
.then((data2) => {console.log(data2);return p3;
})
.then((data3) => {console.log(data3);
})// 依次输出setTimeout1、setTimeout2、setTimeout3

基本用法

1、 new实例化一个promise对象,构造函数中接收一个函数作为参数,该函数支持传入2个参数resolve和reject。

2、将需要处理的异步任务写在该函数内,异步任务执行成功时调用resolve返回结果,执行失败时调用reject回调函数。

3、通过promise.then接收处理成功时响应的数据,catch接收处理失败时响应的数据。

const promise1 = new Promise((resolve, reject) => {axios.get("/api/mock-data/list/v1").then((e) => {if (e.data.status == 200) {resolve(e.data);} else {reject({errCode: -1});}});
});
promise1.then((data) => {console.log('接口返回数据===',data);
})
.catch((err) => {console.log('接口响应错误===',err);
});
// 模拟接口数据1:通过then()获取
{status: 200,message: 'success',data: [{id: 1,name: 'xiaoming',age: '21',job: '前端工程师'}, {id: 2,name: 'xiaozhang',age: '28',job: '后端工程师'}]
}
// 模拟接口数据2:通过catch()捕获
{status: 404,message: 'Not Found',data: null
}

常用API

promise.then():获取异步任务的成功结果,支持2个函数参数(成功和失败回调),一般来说then中只处理成功的

promise.catch():获取异步任务的失败结果,和then函数参数中失败回调作用一样,处理错误,由于Promise抛出错误具有冒泡性质,能够不断传递,会传到catch中,所以一般来说所有错误处理放在catch中,then中只处理成功的,同时catch还会捕捉resolved中抛出的异常(代码报错)

promise.finally():异步任务成功与否,都会执行

Promise.all():Promise.all([promise1,promise2])——参数是对象数组。以慢为准,等数组中所有的promise对象状态为resolved时,该对象就为resolved;只要数组中有任意一个promise对象状态为rejected,该对象就为rejected

const p1 = new Promise((resolve, reject) => {resolve({ errCode: 0 });
});
const p2 = new Promise((resolve, reject) => {resolve({ errCode: -1 });
});
const p3 = new Promise((resolve, reject) => {resolve({ errCode: -2 });
});
const promises = Promise.all([p1, p2, p3]);
promises
.then((data) => {console.log("Promise.all.then===", data);
})
.catch((err) => {console.log("Promise.all.catch===", err);
});
// 运行结果为:Promise.all.then===
//[
//    {
//        "errCode": 0
//    },
//    {
//        "errCode": -1
//    },
//    {
//        "errCode": -2
//    }
//]
const p1 = new Promise((resolve, reject) => {resolve({ errCode: 0 });
});
const p2 = new Promise((resolve, reject) => {reject({ errCode: -1 });
});
const p3 = new Promise((resolve, reject) => {reject({ errCode: -2 });
});
const promises = Promise.all([p1, p2, p3]);
// const promises = Promise.race([p2, p1, p3]);
promises
.then((data) => {console.log("Promise.all.then===", data);
})
.catch((err) => {console.log("Promise.all.catch===", err);
});
// 运行结果为:Promise.all.catch===
//{
//   "errCode": -1
//}

Promise.race():Promise.race([promise1,promise2])——参数是对象数组。以快为准,数组中所有的promise对象,有一个先执行了何种状态,该对象就为何种状态,并执行相应函数

const p1 = new Promise((resolve, reject) => {reject({ errCode: 0 });
});
const p2 = new Promise((resolve, reject) => {resolve({ errCode: -1 });
});
const p3 = new Promise((resolve, reject) => {resolve({ errCode: -2 });
});
const promises = Promise.race([p2, p1, p3]);
promises
.then((data) => {console.log("Promise.all.then===", data);
})
.catch((err) => {console.log("Promise.all.catch===", err);
});
// 运行结果为:Promise.all.then===
//{
//    "errCode": -1
//}

Promise缺点

代码冗余,异步任务通过new Promise包装后,都需要使用then调用,导致一眼看出都是then..then..then,不利于代码维护。

async/await

async/await 是ES7提出的基于Promise的解决异步的最终方案。

async:是一个加在函数前的修饰符,被async定义的函数会默认返回一个Promise对象resolve的值。因此对async函数可以直接then,返回值就是then方法传入的函数。

async fn() {return 123456;
},
this.fn().then((data) => {console.log('async===',data);
})
// 输出为:async=== 123456
// 注意:未加async修饰的函数,是不能直接.then的

await: 也是一个修饰符,只能放在async定义的函数内。可以理解为等待

await 修饰Promise对象:可以获取Promise中返回的内容(resolve或reject的参数),且取到值后语句才会往下执行;

示例:

async fn() {let data = '';axios.get("/api/mock-data/list/v1").then((e) => {data = e.data;});console.log('data===',data);// 输出data值为''
}

await修饰后:new Promise可以省略

async fn() {let data = '';data = await new Promise((resolve, reject) => {axios.get("/api/mock-data/list/v1").then((e) => {resolve(e.data);});});console.log('data===',data);// 输出data为接口返回值
}

总结:await实际会暂停函数的执行,直到promise状态变为完成,然后继续执行。

async fn() {console.log('123');let data1 = await new Promise((resolve, reject) => {axios.get("/api/mock-data/list/v1").then((e) => {resolve(e.data);});});let data2 = await new Promise((resolve, reject) => {setTimeout(() => {resolve('success');}, 3000);});console.log('456');console.log('data1===',data1);console.log('data2===',data2);
},
this.fn();//立即输出123,3秒后分别输出456、data1、data2

tips

当浏览器出现报错Uncaught (in promise) err时,检查是否有reject错误未捕获,增加catch分支即可。

相关文章:

ES6的promise

Promise是什么 1、Promise是js中的一个原生对象,是一种异步编程的解决方案。可以替换掉传统的回调函数解决方案,将异步操作以同步的流程表达出来。 2、Promise有三种状态:pending(初始化)、fulfilled(成功)、rejected(失败) 可以通过resolve(…...

轻松找回:如何在PostgreSQL 16中重置忘记的数据库密码

目录 1. 引言2. PostgreSQL 16的新特性简介3. 解决方法概述4. 方法一:通过修改pg_hba.conf文件重置密码5. 方法二:通过命令行进入单用户模式6. 方法三:使用pgAdmin工具重置密码7. 总结与最佳实践写在以后 1. 引言 你有没有过这样的经历&…...

EVAL长度突破限制

目录 突破15位限制 代码 绕过方式 第一种(使用echo执行) 第二种(使用file_get_content追加文件后进行问件包含) 第三种(使用usort可变长参数) 突破7位限制 第一种(可以使用>创建文件…...

如何判断树上一个点是否在直径上

# 旅游规划 ## 题目描述 W市的交通规划出现了重大问题,市政府下定决心在全市各大交通路口安排疏导员来疏导密集的车流。但由于人员不足,W市市长决定只在最需要安排人员的路口安排人员。 具体来说,W市的交通网络十分简单,由n个…...

docker 部署 RabbitMQ

命令 docker run -d --namerabbitmq \ -p 5671:5671 -p 5672:5672 -p 4369:4369 \ -p 15671:15671 -p 15672:15672 -p 25672:25672 \ -e RABBITMQ_DEFAULT_USERusername\ -e RABBITMQ_DEFAULT_PASSpassword\ -v /usr/local/rabbitmq/data:/var/lib/rabbitmq \ -v /usr/local/r…...

设计模式 - 过滤器模式

💝💝💝首先,欢迎各位来到我的博客!本文深入理解设计模式原理、应用技巧、强调实战操作,提供代码示例和解决方案,适合有一定编程基础并希望提升设计能力的开发者,帮助读者快速掌握并灵活运用设计模式。 💝💝💝如有需要请大家订阅我的专栏【设计模式】哟!我会定…...

使用 Locust 进行本地压力测试

在应用开发和运维过程中,了解应用在高负载情况下的表现至关重要。压力测试可以帮助你识别性能瓶颈和潜在问题。本文将介绍如何使用 Locust 工具进行本地压力测试,模拟高并发场景,并分析测试结果。 1. 什么是 Locust? Locust 是一…...

【图形学】TA之路-矩阵应用平移-旋转-大小

矩阵应用:在 Unity 中,Transform 和矩阵之间的关系非常密切。Transform 组件主要用于描述和控制一个物体在三维空间中的位置、旋转和缩放,而这些操作背后实际上都是通过矩阵来实现的 1. Transform 组件与矩阵的关系 Transform 组件包含以下…...

Spring 循环依赖解决方案

文章目录 1. 循环依赖的产生2. 循环依赖的解决模型3. 基于setter/Autowired 的循环依赖1_编写测试代码2_初始化 Cat3_初始化 Person4_ 回到 Cat 的创建流程5_小结 4. 基于构造方法的循环依赖5. 基于原型 Bean 的循环依赖6. 引人AOP的额外设计7. 总结 IOC 容器初始化bean对象的逻…...

可视化大屏:如何get到领导心目中的“科技感”?

你如果问领导可视化大屏需要什么风格的,领导大概率说科技感的,然后你就去做了,结果被劈了一顿,什么原因?因为你没有get到领导心目中描述的科技感。 一、为什么都喜欢科技感 科技感在可视化大屏设计中具有以下好处&am…...

基于Python的金融数据采集与分析的设计与实现

基于Python的金融数据采集与分析的设计与实现 “Design and Implementation of Financial Data Collection and Analysis based on Python” 完整下载链接:基于Python的金融数据采集与分析的设计与实现 文章目录 基于Python的金融数据采集与分析的设计与实现摘要第一章 绪论1…...

使用Sanic和SSE实现实时股票行情推送

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storm…...

redis散列若干记录

字典 redis本身使用字典结构管理数据 redis使用hash表实现字典结构 使用了什么hash算法 使用SipHash算法,该算法能有效防止Hash表碰撞,并有不错的性能 hash冲突怎么解决 使用链表法解决hash冲突 hash表如何扩容 渐进式扩容,不会引起线程长期阻…...

Java面试八股之什么是STOMP协议

什么是STOMP协议 STOMP(Simple Text Oriented Messaging Protocol)是一种为消息队列和事件驱动架构设计的轻量级协议,主要用于在消息中间件之间进行消息交换。它的设计原则是简单、跨平台和易于实现,这使得STOMP成为许多实时应用…...

【自用】Python爬虫学习(一):爬虫基础与四个简单案例

Python爬虫学习(一) 基础知识四个简单的爬虫案列1.使用urlopen获取百度首页并保存2.获取某翻译单词翻译候选结果3.获取某网页中的书名与价格4.获取某瓣排名前250的电影名称 基础知识 对于一个网页,浏览器右键可以查看页面源代码,…...

[python]uiautomation.WindowControl函数用法

Python UIAutomation 窗口控件 介绍 在本文中,我们将探讨Python UIAutomation库以及如何使用它来控制和自动化Windows应用程序。我们将介绍UIAutomation的基础知识及其功能,并提供代码示例来演示其用法。 什么是UI自动化? UIAutomation是一个…...

学习记录第二十七天

进程 wait函数 功能 等待子进程结束:父进程调用wait函数后,会暂停执行,直到它的某个子进程结束。收集子进程状态:当子进程结束时,wait函数会返回子进程的终止状态,包括是正常终止还是被信号终止等信息。…...

servlet的执行顺序

执行的时候Tomcat先初始化 然后调用 server 根据server来回调请求方式下面会追入源码解释 package com.haogu.servlet;import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.…...

Go语言 类封装和绑定方法

本篇文章主要内容为Go语言类相关操作:封装和绑定方法介绍及示例。 目录 封装 绑定方法 类方法形参 指针形参 设置类方法参数 指针与非指针区别 总结 封装 go语言支持类的操作,但是没有class关键字,使用struct来模拟类。 示例如下&am…...

DirectShow过滤器开发-写WAV音频文件过滤器

下载本过滤器DLL 本过滤器将PCM音频流,或ADPCM,IEEE_FLOAT,ALAW,MULAW,GSM610音频流写入WAV音频文件。 写WAV音频文件过滤器信息 过滤器名称:写WAV 过滤器GUID:{CF704A9C-0C67-4712-BA33-DD0A…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验

Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型

本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文通过代码驱动的方式,系统讲解PyTorch核心概念和实战技巧,涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...

leetcode73-矩阵置零

leetcode 73 思路 记录 0 元素的位置:遍历整个矩阵,找出所有值为 0 的元素,并将它们的坐标记录在数组zeroPosition中置零操作:遍历记录的所有 0 元素位置,将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...

结构化文件管理实战:实现目录自动创建与归类

手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...

Redis上篇--知识点总结

Redis上篇–解析 本文大部分知识整理自网上,在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库,Redis 的键值对中的 key 就是字符串对象,而 val…...

【版本控制】GitHub Desktop 入门教程与开源协作全流程解析

目录 0 引言1 GitHub Desktop 入门教程1.1 安装与基础配置1.2 核心功能使用指南仓库管理日常开发流程分支管理 2 GitHub 开源协作流程详解2.1 Fork & Pull Request 模型2.2 完整协作流程步骤步骤 1: Fork(创建个人副本)步骤 2: Clone(克隆…...