当前位置: 首页 > 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…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...