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

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...