Promise介绍和使用

Promise

Promise是一门新的技术(ES6规范),JS中进行异步编程的新解决方案。(旧的方案是使用回调函数,比如AJAX请求)。
从语法上来说Promise是一个构造函数。
从功能上来说Promise对象用来封装一个异步操作并可以获取其成功/失败的结果值。

Promise初体验

<script>//普通实现异步方法setTimeout()const btn = document.querySelector('#btn');btn.addEventListener('click',()=>{setTimeout(()=>{alert('1秒后执行');},1000);});document.querySelector('#btn1').addEventListener('click',()=>{//使用Promise//1. resolve 函数类型数据,异步执行成功回调//2. reject 函数类型数据,异步执行失败回调const promise = new Promise((resolve,reject)=>{setTimeout(()=>{//获取1-10的随机数let n = Math.floor(Math.random() * (10 - 1 + 1)) + 1;if(n <= 5){resolve(n); //将promise对象状态设置为 成功console.log('resolve');}else{reject(n);//将promise对象状态设置为 失败console.log('resolve');}},1000);});//调用then方法获取异步函数执行状态,执行的是resolve/reject//接受两个函数 resolve & rejectpromise.then((val)=>{alert('resolve ' + val);},(val)=>{alert('reject ' + val);});});</script>

catch方法

const promise = new Promise((resolve,reject)=>{//获取1-10的随机数let n = Math.floor(Math.random() * (10 - 1 + 1)) + 1;if(n<=5){resolve(n);}else{reject(n);}}).then((val)=>{console.log('success' + val);}).catch((err)=>{console.log('failure' + err);});

使用Promise封装AJAX请求

  const btn = document.querySelector('#btn');btn.addEventListener('click',()=>{const promise = sendAJAX('http://localhost/test');//调用then方法promise.then((val)=>{//成功console.log(val);},(val)=>{//失败console.log(val);});});function sendAJAX(url){const promise = new Promise((resolve,reject)=>{//1. AJAX请求 , 创建http客户端const http = new XMLHttpRequest();//2. 初始化http.open('GET',url);//3. 发送请求http.send();//4. 处理响应结果http.onreadystatechange = function(){if(http.readyState === 4){if(http.status == 200){//成功resolve(http.response);}else{//失败reject(http.status);}}}});return promise;}

Promise属性

PromiseState:Promise状态

  1. pending:等待,初始化默认值
  2. resolved / fullfilled:表示成功
  3. rejected:表示失败

PromiseResult:保存着对象的结果。成功/失败

  1. resolve():resolve方法会把状态改为成功,并且存成功的结果
  2. reject():reject方法会把状态改为失败,并且保存失败结果

Promise方法

  1. Promise.resolve()方法:如果传入的参数是非Promise类型的对象,则返回结果是成功的Promise对象,如果传入的参数为Promise对象,则参数的结果决定了resolve的结果
    let promise = Promise.resolve(1);console.log(promise);promise = Promise.resolve(new Promise((resolve,reject)=>{//resolve();reject();}));console.log(promise);
    
  2. Promise.reject()方法:快速的返回一个失败的Promise对象,无论传入什么,返回结果都是失败。
    let promise = Promise.reject(1)
    console.log(promise);
    
  3. Promise.all()方法:传入Promise数组,只有所有的Promise对象都成功才成功,只要有一个失败就直接失败。成功的返回结果是全部的Promise对象。无论有多少个失败,都会执行完全部的Promise。
      const p1 = new Promise((resolve,reject)=>{resolve();console.log(1)})const p2 = new Promise((resolve,reject)=>{reject();console.log(2)})const p3 = new Promise((resolve,reject)=>{reject();console.log(3)})let promises = Promise.all([p1,p2,p3])console.log(promises);
    
  4. Promise.race()方法:传入Promise数组,第一个完成的Promise的结果的状态就是最终的结果状态。结果也是第一个成功返回的结果。
      const p1 = new Promise((resolve,reject)=>{resolve();console.log(1)})const p2 = new Promise((resolve,reject)=>{reject();console.log(2)})const p3 = new Promise((resolve,reject)=>{reject();console.log(3)})let promises = Promise.race([p1,p2,p3])console.log(promises);
    

Promise关键知识

  1. 如何改变Promise状态
    const promise = new Promise((resolve,reject)=>{//1. 调用resolve()方法,改为成功状态resolve();//2. 调用reject()方法,改为失败状态reject();//3. 抛出一个异常改为失败状态 throwthrow 'has error';})
    
  2. 可以为Promise指定多个then函数,都会被执行
      const promise = new Promise((resolve,reject)=>{resolve();}).then(()=>{console.log(1);}).then(()=>{console.log(2);}).then(()=>{console.log(3);});
    
  3. then和catch函数,是执行器里执行reslove()或者reject()方法才会执行
    const promise = new Promise((resolve,reject)=>{setTimeout(()=>{console.log('setTimeout');resolve();},2000)}).then(()=>{console.log(1);}).then(()=>{console.log(2);}).then(()=>{console.log(3);});
    

Promise链式调用

Promise的then方法可以返回Promise对象,当返回Promise对象时,后续的then方法接受到的参数是上一个then返回Promise返回的对象的返回值,如下。
也就是说,可以实现对异步操作的链式调用,只用上一个异步执行接受,有返回值的时候才会执行下一个then,不需要自己去判断线程的状态。

 //三个异步方法,最后输出为 1 2 3const promise = new Promise((resolve,reject)=>{//1. 第一个异步方法setTimeout(()=>{resolve(1);},2000)}).then((val)=>{console.log(val);return new Promise((resolve,reject)=>{//2. 第二个异步方法setTimeout(()=>{resolve(2);},1000)})}).then((val)=>{console.log(val);return new Promise((resolve,reject)=>{//3. 第三个异步方法setTimeout(()=>{resolve(3);},1000)})}).then((val)=>{console.log(val);});

链式调用的异常穿透

链式调用过程中,只需要有一个catch,如果其中某一环节出错,抛出异常throw 'error msg',则会执行catch的函数,不会继续执行接下来的任务。

 const promise = new Promise((resolve,reject)=>{setTimeout(()=>{resolve(1);},2000)}).then((val)=>{console.log(val);return new Promise((resolve,reject)=>{setTimeout(()=>{//抛出异常直接执行catch,不会执行继续执行,因为没有执行到resolve()方法throw 'error';resolve(2);},1000)})}).then((val)=>{console.log(val);return new Promise((resolve,reject)=>{setTimeout(()=>{resolve(3);},1000)})}).then((val)=>{console.log(val);}).catch(err=>{console.log(err);});

中断链式调用

  1. 中断链式调用的方法是返回一个空函数的Promise对象new Promise(()=>{})这样就不会跳入下一个then里面
  2. 在某些业务场景中可以抛出异常来中断Promise,如上异常穿透也是终止了链式调用。这种直接调用了catch,也属于另类的终止
 promise = new Promise((resolve,reject)=>{setTimeout(()=>{resolve(1);},2000)}).then((val)=>{console.log(val);//终止链式调用return new Promise(()=>{})}).then((val)=>{console.log(2);return new Promise((resolve,reject)=>{setTimeout(()=>{resolve(3);},1000)})}).then((val)=>{console.log(val);}).catch(err=>{console.log(err);});

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

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

相关文章

生成式AI赋能千行百业加速创新,2023亚马逊云科技re:Invent行业盘点

2023亚马逊云科技re:Invent全球大会已于上周圆满闭幕&#xff0c;在本次大会中&#xff0c;亚马逊云科技又为大家带来了很多功能/项目迭代更新&#xff0c;也重磅发布了很多全新的功能。今天从行业视角来盘点回顾哪些重磅发布适用于垂直行业客户&#xff0c;以及面向汽车、制造…

ChatGLM3-6B和langchain阿里云部署

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、ChatGLM3-6B部署搭建环境部署GLM3 二、Chatglm2-6blangchain部署三、Tips四、总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; …

ffmpeg之ffprobe.c源码分析一---大流程及核心代码分析

文章目录 前言为什么学习ffprobe源码源码调试main()函数重要流程函数分析open_input_file函数分析avformat_match_stream_specifier函数分析read_packets函数分析本篇文章带你打通ffprobe源码的脉络。 关注公众号免费看: 前言 注:本文章全凭个人经验以及平时学习所记录,由…

gdal合成多个波段

def synthesis_bands(dst_list, outfile):"""将多光谱波段合成一个tif:param dst_list: 输入待合成文件的列表:param outfile: 影像的输出文件夹"""dataset_init gdal.Open(dst_list[0])# 创建待输出的图tiff_driver gdal.GetDriverByName(GTi…

【MySQL进阶】索引使用

一、索引使用 1.验证索引效率 tb_sku 这张表中准备了 1000w 的记录。 我用夸克网盘分享了「1000w的模拟数据」链接&#xff1a;https://pan.quark.cn/s/15cf665202b2 这张表中id为主键&#xff0c;有主键索引&#xff0c;而其他字段是没有建立索引的。 我们先来查询其中的…

JS基础之原型原型链

JS基础之原型&原型链 原型&原型链构造函数创建对象prototypeprotoconstructor实例与原型原型的原型原型链其他constructorproto继承 原型&原型链 构造函数创建对象 我们先使用构造函数创建一个对象&#xff1a; function Person(){ } var person new Person();…

多窗口文件管理工具Q-Dir安装以及使用教程

软件介绍 Q-Dir 是一款功能强大的Windows资源管理器&#xff0c;可以非常方便的管理你的各种文件。Q-Dir有4 个窗口&#xff0c;特别适用于频繁在各个目录间跳跃复制粘贴的情况&#xff0c;每个窗口都可以方便的切换目录&#xff0c;以不同颜色区分不同类型的文件&#xff0c;…

(企业项目)微服务项目解决跨域问题:

前后端分离项目中前端出现了跨域的问题 在网关模块配置文件中添加 配置 application.properties # 允许请求来源&#xff08;老版本叫allowedOrigin&#xff09; spring.cloud.gateway.globalcors.cors-configurations.[/**].allowedOriginPatterns* # 允许携带的头信息 spri…

idea__SpringBoot微服务06——静态资源(新依赖),首页和图标定制

静态资源 一、静态资源二、首页和图标定制————————创作不易&#xff0c;如觉不错&#xff0c;随手点赞&#xff0c;关注&#xff0c;收藏(*&#xffe3;︶&#xffe3;)&#xff0c;谢谢~~ 新依赖&#xff1a;jquery的 <dependency><groupId>org.webjars&…

说说设计体系、风格指南和模式库

目录 一、定义 二、设计体系 2.1 Design system 2.2 风格指南 2.3 Component 三、样式库 一、定义 设计体系&#xff08;Design system&#xff09;&#xff1a;可共享的设计语言的基础合集&#xff0c;包含了设计价值&#xff0c;语义&#xff0c;语法和上下文。 风格…

matplotlib 默认属性和绘图风格

matplotlib 默认属性 一、绘图风格1. 绘制叠加折线图2. Solarize_Light23. _classic_test_patch4. _mpl-gallery5. _mpl-gallery-nogrid6. bmh7. classic8. fivethirtyeight9. ggplot10. grayscale11. seaborn12. seaborn-bright13. seaborn-colorblind14. seaborn-dark15. sea…

Chart 7 内存优化

文章目录 前言7.1 Adreno GPU OpenCL内存7.1.1 内存声明周期7.1.2 Loacl Memory7.1.3 Constant memory(常量内存)7.1.4 Private Memory7.1.5 Global Memory7.1.5.1 Buffer Object7.1.5.2 Image Object7.1.5.3 Image object vs. buffer object7.1.5.4 Use of both Image and buf…

C语言数据结构-双向链表

文章目录 1 双向链表的结构2 双向链表的实现2.1 定义双向链表的数据结构2.2 打印链表2.3 初始化链表2.4 销毁链表2.5 尾插,头插2.6 尾删,头删2.7 根据头次出现数据找下标2.8 定点前插入2.9 删除pos位置2.10 定点后插入 3 完整代码3.1 List.h3.2 Lish.c3.3 test.c 1 双向链表的结…

ajax中get和post的区别,datatype返回的数据类型有哪些?web开发中数据提交的几种方式,有什么区别。百度使用哪种方式?

在Ajax中&#xff0c;GET和POST是两种常见的HTTP请求方法。它们有以下区别&#xff1a; GET请求&#xff1a;使用GET请求时&#xff0c;参数数据会附加在URL的末尾&#xff0c;以查询字符串的形式发送给服务器。GET请求是幂等的&#xff0c;也就是说多次发送相同的GET请求&…

键盘打字盲打练习系列之矫正坐姿——4

一.欢迎来到我的酒馆 盲打&#xff0c;矫正坐姿&#xff01; 目录 一.欢迎来到我的酒馆二.继续练习二.矫正坐姿1.键鼠快速选购指南2.椅子快速选购指南 三.改善坐姿建议 二.继续练习 前面的章节&#xff0c;我们重点向大家介绍了主键盘区指法和键盘键位。经过一个系列的教程学习…

Mybatis环境搭建

1、开发环境 IDE&#xff1a;IntelliJ IDEA 2022.2.1 (Ultimate Edition) 构建工具&#xff1a;maven 3.6.1 MySQL版本&#xff1a;MySQL 5.7 MyBatis版本&#xff1a;MyBatis 3.5.14 2、工程创建 创建一个Maven工程giser-java-mybatis-demo 基础依赖如下&#xff1a; &…

【Python】pip命令及使用

PIP命令 下面是一个整理成表格的pip命令及使用的示例&#xff1a; 命令使用示例说明pip install <package>pip install requests安装名为"requests"的包pip uninstall <package>pip uninstall requests卸载名为"requests"的包pip listpip li…

用友U8 Cloud 多处反序列化RCE漏洞复现

0x01 产品简介 用友U8 Cloud是用友推出的新一代云ERP,主要聚焦成长型、创新型企业,提供企业级云ERP整体解决方案。 0x02 漏洞概述 用友U8 Cloud存在多处(TableInputOperServlet、LoginServlet 、FileTransportServlet、CacheInvokeServlet、ActionHandlerServlet、Servle…

12.9每日一题(备战蓝桥杯循环结构)

12.9每日一题&#xff08;备战蓝桥杯循环结构&#xff09; 题目 2165: 求平均年龄题目描述输入输出样例输入样例输出来源/分类 题解 2165: 求平均年龄题目 2166: 均值题目描述输入输出样例输入样例输出来源/分类 题解 2166: 均值题目 2167: 求整数的和与均值题目描述输入输出样…

GB/T 43212-2023 竹炭板检测

竹炭塑复合板是指以竹炭粉为主要原料&#xff0c;与塑料及其他助剂复配混合&#xff0c;经熔融挤出或模压成型等工艺制成的板材。 GB/T 43212-2023 竹炭板测试&#xff1a; 测试项目 测试方法 外观 GB/T 43212 尺寸 GB/T 19367 含水率 GB/T 17657 密度 GB/T 17657 吸…