Promise用法

学习了promise之后,有点懂但让我说又说不出来,参考别人的记录一下。

1.什么是promise?

2.promise解决了什么问题

3.es6 promise语法

(1)then链式操作语法

(2)catch的语法

(3)all的语法

(4)race的语法

一、什么是Promise?我们用Promise来解决什么问题?

1.什么是promise?

Promise 是异步编程的一种解决方案:从语法上讲,promise是一个对象,从它可以获取异步操作的消息;promise有三种状态: pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。创造promise实例后,它会立即执行。

2.promise解决了什么问题?

  • 回调地狱问题。代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象
  • promise可以支持多个并发的请求,获取并发请求中的数据

这个promise可以解决异步的问题,本身不能说promise是异步的

 二、es6 promise用法大全

Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法。

那就new一个

let p = new Promise((resolve, reject) => {//做一些异步操作setTimeout(() => {console.log('执行完成');resolve('我是成功!!');}, 2000);
});

Promise的构造函数接收一个参数:函数,并且这个函数需要传入两个参数:

  • resolve :异步操作执行成功后的回调函数
  • reject:异步操作执行失败后的回调函数

then 链式操作的用法  :

从表面上看,Promise只是能够简化层层回调的写法,而实质上,Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多。所以使用Promise的正确场景是这样的:

p.then((data) => {console.log(data);
})
.then((data) => {console.log(data);
})
.then((data) => {console.log(data);
});

reject的用法 :

把Promise的状态置为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。看下面的代码。

    let p = new Promise((resolve, reject) => {//做一些异步操作setTimeout(function(){var num = Math.ceil(Math.random()*10); //生成1-10的随机数if(num<=5){resolve(num);}else{reject('数字太大了');}}, 2000);});p.then((data) => {console.log('resolved',data);},(err) => {console.log('rejected',err);}); 

 then中传了两个参数,then方法可以接受两个参数,第一个对应resolve的回调,第二个对应reject的回调。所以我们能够分别拿到他们传过来的数据。多次运行这段代码,你会随机得到下面两种结果:                    

或者 

 catch的用法

我们知道Promise对象除了then方法,还有一个catch方法,它是做什么用的呢?其实它和then的第二个参数一样,用来指定reject的回调。用法是这样:

p.then((data) => {console.log('resolved',data);
}).catch((err) => {console.log('rejected',err);
});

效果和写在then的第二个参数里面一样。不过它还有另外一个作用:在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中。请看下面的代码: 

p.then((data) => {console.log('resolved',data);console.log(somedata); //此处的somedata未定义
})
.catch((err) => {console.log('rejected',err);
});

在resolve的回调中,我们console.log(somedata);而somedata这个变量是没有被定义的。如果我们不用Promise,代码运行到这里就直接在控制台报错了,不往下运行了。但是在这里,会得到这样的结果:

 也就是说进到catch方法里面去了,而且把错误原因传到了reason参数中。即便是有错误的代码也不会报错了,这与我们的try/catch语句有相同的功能

all的用法:谁跑的慢,以谁为准执行回调。all接收一个数组参数,里面的值最终都算返回Promise对象

Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。看下面的例子:

let Promise1 = new Promise(function(resolve, reject){})
let Promise2 = new Promise(function(resolve, reject){})
let Promise3 = new Promise(function(resolve, reject){})let p = Promise.all([Promise1, Promise2, Promise3])p.then(funciton(){// 三个都成功则成功  
}, function(){// 只要有失败,则失败 
})

有了all,你就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据,是不是很酷?有一个场景是很适合用这个的,一些游戏类的素材比较多的应用,打开网页时,预先加载需要用到的各种资源如图片、flash以及各种静态文件。所有的都加载完后,我们再进行页面的初始化。

race的用法:谁跑的快,以谁为准执行回调

race的使用场景:比如我们可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作,代码如下:

 //请求某个图片资源function requestImg(){var p = new Promise((resolve, reject) => {var img = new Image();img.onload = function(){resolve(img);}img.src = '图片的路径';});return p;}//延时函数,用于给请求计时function timeout(){var p = new Promise((resolve, reject) => {setTimeout(() => {reject('图片请求超时');}, 5000);});return p;}Promise.race([requestImg(), timeout()]).then((data) =>{console.log(data);}).catch((err) => {console.log(err);});

requestImg函数会异步请求一张图片,我把地址写为"图片的路径",所以肯定是无法成功请求到的。timeout函数是一个延时5秒的异步操作。我们把这两个返回Promise对象的函数放进race,于是他俩就会赛跑,如果5秒之内图片请求成功了,那么遍进入then方法,执行正常的流程。如果5秒钟图片还未成功返回,那么timeout就跑赢了,则进入catch,报出“图片请求超时”的信息。运行结果如下:

1.Promise 有几种状态?
3种。
 pending(等待态)

 fulfiled(成功态)

 rejected(失败态)


2.Promise得状态是否可变
不可变


3.Promise如何解决地狱回调?
地狱回调:发送多个异步请求时,每个请求之间相互都有关联,会出现第一个请求成功后再做下一个请求的情况。我们往往会用嵌套的方式来解决这种情况,这就形成了回调地狱。
then里面可以return Promise,来防止地狱回调


4.Promise有哪些方法?他们的应用场景是什么?(all/race)
Promise.all()接收一个对象数组为参数,处理并进行异步操作,如果成功就返回一个数组,失败就返回数据,一旦失败就不会继续往下走
Promise.race()成功返回一个数组,就返回那个成功的数组,不管结果本身是成功还是失败


5.如何让Promise顺序执行(async/await)
async用于函数声明,表示声明的函数为异步函数,这个函数返回一个Promise对象(resolve)
await表示在这里等待promise返回结果
async function getData(){
         await promise1.then(v => console.log(v))
}

原文链接:https://blog.csdn.net/weixin_42451032/article/details/115647237 


原文链接:https://juejin.cn/post/6844903607968481287

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

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

相关文章

Git Bash 教程!【不是所有人都会用Git】

我不太会用github...... 写这篇文章希望能顺利...... 【写在前面】介绍一下git bash的复制粘贴的快捷键&#xff0c;以防后续不会&#xff1a; 开始&#xff1a; 首先下一个windows&#xff1a;git for windows(地址&#xff1a;Git - Downloading Package (git-scm.com)) &a…

基于遗传算法的试题组卷(二)

实例讲解 一、准备工作 1、问题实体 问题实体包含编号、类型&#xff08;类型即题型&#xff0c;分为五种&#xff1a;单选&#xff0c;多选&#xff0c;判断&#xff0c;填空&#xff0c;问答&#xff0c; 分别用1、2、3、4、5表示&#xff09;、分数、难度系数、知识点。一…

【MySQL】触发器 (十二)

🚗MySQL学习第十二站~ 🚩本文已收录至专栏:MySQL通关路 ❤️文末附全文思维导图,感谢各位点赞收藏支持~ 一.引入 触发器是与表有关的数据库对象,作用在insert/update/delete语句执行之前(BEFORE)或之后(AFTER),自动触发并执行触发器中定义的SQL语句集合。它可以协助应…

解决Win11右键菜单问题

✅作者简介&#xff1a;大家好&#xff0c;我是Cisyam&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Cisyam-Shark的博客 &#x1f49e;当前专栏&#xff1a; 程序日常 ✨特色专栏&…

【MyBatis】 框架原理

目录 10.3【MyBatis】 框架原理 10.3.1 【MyBatis】 整体架构 10.3.2 【MyBatis】 运行原理 10.4 【MyBatis】 核心组件的生命周期 10.4.1 SqlSessionFactoryBuilder 10.4.2 SqlSessionFactory 10.4.3 SqlSession 10.4.4 Mapper Instances 与 Hibernate 框架相比&#…

【HAL库】STM32CubeMX开发----STM32F407----LAN8720A----移植FreeModbus实现ModbusTCP

前言 本次实验以 STM32F407VET6 芯片为MCU&#xff0c;使用 25MHz 外部时钟源。 以太网PHY层芯片为 LAN8720A&#xff0c;移植FreeModbus实现ModbusTCP网口通信。 具体内容参考文章&#xff1a;【HAL库】STM32CubeMX开发----STM32F407----ETHLAN8720ALWIP----ping通 本次移植…

零基础强化学习入门分享

&#xff08;一&#xff09;前言&#xff1a;强化学习入门顺序。 以前主要学习硬件PCB单片机等知识&#xff0c;后来接触的项目也大多与电气相关&#xff0c;从一窍不通到稍微找到点门道&#xff0c;中间走过不少弯路&#xff0c;误打误撞中&#xff0c;也留下了一些经验。 我的…

微服务——elasticsearch

初识ES——什么是elasticsearch elasticsearch的发展 初识ES——正向索引和倒排索引 初识ES——es与mysql的概念对比 类比到mysql中是表结构约束 概念对比 初始ES——安装es和kibana 1.部署单点es 1.1创建网络 要安装es容器和kibana容器并让他们之间相连&#xff0c;这里…

RabbitMQ-API

这里写目录标题 Hello word 模式添加依赖生产者消费者获取信道工具类 Work Queues模式消费者代码 C1开启多线程运行启动 消费者代码 C2生产者代码 消息应答自动应答消息应答的方法Multiple 的解释消息自动重新入队消息手动应答代码消费者API 队列持久化消息持久化不公平分发消息…

redis 高级篇 redis 源码的读取分析

一 redis源码分析 1.1 源码分析 1每一个kv键值对应有一个dictEntry。 2.底层数据结构

mysql数据库迁移

目录 背景迁移数据库 背景 公司有个项目&#xff0c;刚开始数据量不是大的时候&#xff0c;数据库和服务上的所有应用数据都放在一个旧小盘中&#xff0c;随着项目数据的增长&#xff0c;旧的磁盘被占满了&#xff0c;导致系统无法写入数据&#xff0c;我和同事排查了很长时间…

C++运算符重载详解(赋值、流插入流提取、前置后置++、取地址)

C运算符重载详解 基本介绍运算符重载案列1. 赋值运算符重载2. 前置和后置重载3. cout&#xff0c;cin(流插入&#xff0c;流提取重载)4. 取地址重载 基本介绍 C为了增强代码的可读性引入了运算符重载&#xff0c;运算符重载是具有特殊函数名的函数&#xff0c;也具有其 返回值…

生态共建丨YashanDB与构力科技完成兼容互认证

近日&#xff0c;深圳计算科学研究院崖山数据库系统YashanDB V22.2与北京构力科技有限公司BIMBase云平台完成兼容性互认证。经严格测试&#xff0c;双方产品完全兼容、运行稳定。 崖山数据库系统YashanDB是深算院自主研发设计的新型数据库系统&#xff0c;融入原创理论&#xf…

CAD随机球体颗粒过渡区3D插件

插件介绍 CAD随机球体颗粒&过渡区3D插件可用于在AutoCAD软件内生成随机分布的球体及球体外侧过渡区部件&#xff0c;适用于科研绘图、有限元建模如混凝土细观、颗粒增强复合材料、随机三维骨料及过渡区等方面的应用。 插件可指定的参数有模型的长、宽、高&#xff1b;球…

SpringBoot单元测试

目录 1.什么是单元测试? 2.单元测试有哪些好处? 3.Spring Boot单元测试使⽤ 单元测试的实现步骤 1. ⽣成单元测试类 2. 添加单元测试代码 2.1 .添加Spring Boot框架测试注解:SpringBootTest 2.2 添加单元测试业务逻辑 简单的断⾔说明 1.什么是单元测试? 单元测试(un…

RPC框架引入zookeeper服务注册与服务发现

Zookeeper概念及其作用 ZooKeeper是一个分布式的&#xff0c;开放源码的分布式应用程序协调服务&#xff0c;是Google的Chubby一个开源的实现&#xff0c;是大数据生态中的重要组件。它是集群的管理者&#xff0c;监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理…

使用 GitHub Copilot 进行 Prompt Engineering 的初学者指南(译)

文章目录 什么是 GitHub Copilot ?GitHub Copilot 可以自己编码吗&#xff1f;GitHub Copilot 的底层是如何工作的&#xff1f;什么是 prompt engineering?这是 prompt engineering 的另一个例子 使用 GitHub Copilot 进行 prompt engineering 的最佳实践提供高级上下文&…

Springboot -- 按照模板生成docx、pdf文件,docx转pdf格式

使用 poi-tl 根据模板生成 word 文件。 使用 xdocreport 将 docx 文件转换为 pdf 文件。 xdocreport 也支持根据模板导出 word &#xff0c;但是 poi-tl 的功能更齐全&#xff0c;操作更简单&#xff0c;文档清晰。 poi-tl 、xdocreport 内部均依赖了 poi &#xff0c;要注意两…

uniapp 全局数据(globalData)的设置,获取,更改

globalData&#xff0c;这是一种简单的全局变量机制。这套机制在uni-app里也可以使用&#xff0c;并且全端通用 因为uniapp基本上都是将页面&#xff0c;或者页面中相同的部分&#xff0c;进行组件化&#xff0c;所以会存在父&#xff0c;子&#xff0c;&#xff08;子&#xf…

【数据挖掘竞赛】——科大讯飞:锂离子电池生产参数调控及生产温度预测挑战赛

🤵‍♂️ 个人主页:@Lingxw_w的个人主页 ✍🏻作者简介:计算机科学与技术研究生在读 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ ​ 【科大讯飞】报名链接:https://challenge.xfyun.cn?invitaC…