ES6新标准下JS异步编程Promise解读

ES5及以下,要实现复杂的异步编程,需要大量运用回调函数,每一个回调函数(JS引擎把它当作一个代码块)依次进入单线程(JS)任务队伍依次执行,而每个回调函数中的执行正确与否无法及时判断,当中信息反馈及显示都只会在最外层函数执行完毕后才反馈给你,让你只能猜测或分析找问题,这将造成大量无法理解的情况出现。对于复杂嵌套回调问题,你将不得不花费大量精力去跟踪各个回调函数运行及清理相互影响。

ES6新标准引入Promise对上述问题进行解决,它的核心思想,是将上一次函数执行返回一个Promise对象,明确指示代码是否成功执行,则你可以基于此成功与否判断,以链式编程方式将复杂嵌套回调函数转换为简单流程化式的形式完成目标任务。

一、Promise的基本用法

每个Promise都会经历一个短暂的生命周期,当处于进行中时标记为pending状态,一旦异步操作结束,Promise标记为settled状态,如果操作出现错误或未完成,标记为unsettle状态。其内部属性[[PromiseState]],分别对应这三种状态,分别是”pending”、“fulfilled”和”rejected”。其内部会自动调用then()方法响应fulfilled成功状态,catch()方法响应rejected。

Then()方法调用时,与异步操作相关的附加数据都会传递给这个完成响应函数。Catch()调用时,所有与失败状态相关的附加数据都会传递给这个拒绝响应函数。

1.基本用法

Promise构造函数可以创建Promise,构造函数接受两个参数,分别是resolve()函数与reject()函数,执行成功完成时调用resolve()函数,失败时则调用reject()函数。

Promise.resolve方法是将一个对象转换成Promise对象,如果入参是一个Promise对象,则直接返回该对象;如果入参是一个thenale对象(表示该对象已经调用了then方法),则返回的是一个新的Promise对象;如果无任何参数,则返回一个fulfilled状态的Promise对象。

Promise.reject方法可以快速返回被rejected的Promise对象。该方法接收一个参数作为入参,这个参数将成来被rejected对象的reason属性,传给rejected回调函数。

       let promise1=new Promise(function(resolve,reject){//模拟函数成功执行

              resolve("成功");

       });

       promise1.then(function(contents){

              console.log(contents);//输出---成功

       });

       let promise2=new Promise(function(resolve,reject){//模拟函数拒绝执行

              reject(new Error("拒绝"));

       });

       promise2.catch(function(err){

              console.log(err);//输出---Error:拒绝

       });

2.具体运用实例

function readNumber(num){//定义Promise实例函数

       return new Promise(function(resolve,reject){

                     if(num<0){

                            reject("输入的数字小于0,拒绝兑换");

                            return;

                     }

                     resolve("输入的数字大于0,执行兑换");

       });

}

let promise1=readNumber(45);//执行成功输入

promise1.then(function(contents){

       console.log(contents);//输出结果:输入的数字大于0,执行兑换

});

promise1.catch(function(err){

       console.log(err);//此函数不会被调用,故无此输出

});

let promise2=readNumber(-6);//执行失败输入

promise2.then(function(contents){

       console.log(contents);//此函数不会被调用,故无此输出

});

promise2.catch(function(err){

       console.log(err);//输入的数字小于0,拒绝兑换

});

二、Promise的串联(链式)用法

Promise每次调用then()方法和catch()方法时,实际上创建了另一个Promise,只有当第一个Promise完成或被拒绝时,第二个才会被解决。因此,就给解决复杂问题链式化提供了条件,而不是用复杂或嵌套式回调函数去解决。其写法如下:

Let p1=new Promise(function(resolve,reject){ });

P1.then(function(){ }).then(funciton(){ })…

以上述实例为具体实现,如下:

function readNumber(num){//定义Promise实例函数

       return new Promise(function(resolve,reject){

                     if(num<0){

                            reject("输入的数字小于0,拒绝兑换");

                            return;

                     }

                     resolve("输入的数字大于0,执行兑换");

       });

}

let promise1=readNumber(45);//执行成功输入

promise1.then(function(contents){

       console.log(contents);//输出结果:输入的数字大于0,执行兑换

}).then(function(){

       console.log("由于有兑换劵,就可以进入购买了");//输出结果:由于有兑换劵,就可以进入购买了

});

let promise2=readNumber(-8);//执行失败输入

promise2.then(function(contents){

       console.log(contents);//输出结果:输入的数字大于0,执行兑换

}).then(function(){

       console.log("由于有兑换劵,就可以进入购买了");//无输出结果:由于readeNumber输入的是-8,第一个then不满足,为拒绝状态,因而第二个then没有调用,而第三个then是基于第二个then呈错误状态的,所有第三个then被执行

}).catch(function(){

       console.log("由于没有有兑换劵,无法进入");//输出结果:由于没有有兑换劵,无法进入

})

三、多Promise响应用法

    如果你想通过多个Promise来决定下一步的操作,则可以使用ES6提供的Promise.all()和Promise.race()两个方法来监听多个Promise。

    1.Promise.all()方法

Promise.all()方法只接受一个参数并返回一个Promise,该参数是一个含有多个受监视Promise的可迭代对象(例如,一个数组),只有当可迭代对象中所的Promise都被解决后返回的Promise才会被解决,只有当可迭代对象中所有Promise都被完成返回后的Promise才会被完成。

let p1=new Promise(function(resolve,reject){

       resolve(42);

});

let p2=new Promise(function(resolve,reject){

       resolve(43);

});

let p3=new Promise(function(resolve,reject){

       resolve(44);

});

let p4=Promise.all([p1,p2,p3]);

p4.then(function(value){ //因为P4呈完成状态,所以没有调用catch,而是调用的then方法

       console.log(Array.isArray(value));//输出结果:true

       console.log(value[0]);//输出结果:42

       console.log(value[1]);//输出结果:43

       console.log(value[2]);//输出结果:44

})

    上述例中,只有当迭代中所有都完成,P4才呈完成状态;反之,只要有一个被拒绝,那么返回的Promise没等其他后面Promise完成就立即呈拒绝状态。如下:

    let p1=new Promise(function(resolve,reject){

              resolve(42);

       });

       let p2=new Promise(function(resolve,reject){

              reject(43);

       });

       let p3=new Promise(function(resolve,reject){

              resolve(44);

       });

       let p4=Promise.all([p1,p2,p3]);

       p4.catch(function(value){//因为P4呈拒绝状态,所以没有调用then,而是调用的catch方法

              console.log(Array.isArray(value));//输出结果:false

              console.log(value);//输出结果:43

       });

2.Promise.race()方法

Promise.race()方法也监听多个Promise,与Promise.all方法不一样,它只要有一相Promise被解决则立即返回呈解决状态,无须等到所有的Promise都被解决。

let p1=new Promise(function(resolve,reject){

       resolve(42);

});

let p2=new Promise(function(resolve,reject){

       resolve(43);

});

let p3=new Promise(function(resolve,reject){

       resolve(44);

});

let p4=Promise.race([p1,p2,p3]);

p4.then(function(value){//只要p1呈完成状态,就立即返回呈完成状态,其他后面Promise则被忽略

       console.log(Array.isArray(value));//输出结果:false

       console.log(value);//输出结果:42

});

实际上,传给Promise.race()方法的Promise会进行竞选,以决出哪一个先被解决完成,就选哪一个,并以最先解决状态而呈相同状态,其他的则被忽略。

let p1=new Promise(function(resolve,reject){

       setTimeout(function(){resolve(42);},200);

});

let p2=new Promise(function(resolve,reject){

       resolve(43);

});

let p3=new Promise(function(resolve,reject){

       resolve(44);

});

let p4=Promise.race([p1,p2,p3]);

p4.then(function(value){//由于p1被延迟执行,所以p2最先呈完成状态,故最后输出为p2状态

       console.log(Array.isArray(value));//输出结果:false

       console.log(value);//输出结果:43

});

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

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

相关文章

【ShuQiHere】 探索数据挖掘的世界:从概念到应用

&#x1f310; 【ShuQiHere】 数据挖掘&#xff08;Data Mining, DM&#xff09; 是一种从大型数据集中提取有用信息的技术&#xff0c;无论是在商业分析、金融预测&#xff0c;还是医学研究中&#xff0c;数据挖掘都扮演着至关重要的角色。本文将带您深入了解数据挖掘的核心概…

如何快速上手一个Github的开源项目

程序研发领域正是有一些热衷开源的小伙伴&#xff0c;技能迭代才能如此的迅速&#xff0c;因此&#xff0c;快速上手一个GitHub上的开源项目&#xff0c;基本上已经变成很个程序员小伙伴必须掌握的技能&#xff0c;因为终究你会应用到其中的一个或多个项目&#xff0c;帮助自己…

【计算机网络篇】电路交换,报文交换,分组交换

本文主要介绍计算机网络中的电路交换&#xff0c;报文交换&#xff0c;分组交换&#xff0c;文中的内容是我认为的重点内容&#xff0c;并非所有。参考的教材是谢希仁老师编著的《计算机网络》第8版。跟学视频课为河南科技大学郑瑞娟老师所讲计网。 目录 &#x1f3af;一.划分…

【Windows 同时安装 MySQL5 和 MySQL8 - 详细图文教程】

卸载 MySQL 参考文章&#xff1a; 完美解决Mysql彻底删除并重装_怎么找到mysql并卸载-CSDN博客使用命令卸载mysql_卸载mysql服务命令-CSDN博客 先管理员方式打开 cmd &#xff0c;切换到 MySQL 安装目录的 bin 文件夹下&#xff0c;执行如下命令&#xff0c;删除 MySQL 服务mys…

Blender软件三大渲染器Eevee、Cycles、Workbench对比解析

Blender 是一款强大的开源3D制作平台&#xff0c;提供了从建模、雕刻、动画到渲染、后期制作的一整套工具&#xff0c;广泛应用于电影、游戏、建筑、艺术等领域。 渲染101云渲染云渲6666 相比于其他平台&#xff0c;如 Autodesk Maya、3ds Max 或 Cinema 4D&#xff0c;Blende…

neo4j关系的创建删除 图的删除

关系的创建和删除 关系创建 CREATE (:Person {name:"jack"})-[:LOVE]->(:Person {name:"Rose"})已有这个关系时&#xff0c;merge不起效果 MERGE (:Person {name:"Jack" })-[:LOVE]->(:Person {name:"Rose"})关系兼顾节点和关…

C++ 进阶之路:非类型模板参数、模板特化与分离编译详解

目录 非类型模版参数 类型模板参数 非类型模板参数 非类型模板参数的使用 模板的特化 函数模板的特化 类模板的特化 全特化与偏特化 偏特化的其它情况 模板的分离编译 什么是分离编译 为什么要分离编译 为什么模板不能分离编译 普通的类和函数都是可以分离编译的…

【学习笔记】数据结构(六 ①)

树和二叉树 &#xff08;一&#xff09; 文章目录 树和二叉树 &#xff08;一&#xff09;6.1 树(Tree)的定义和基本术语6.2 二叉树6.2.1 二叉树的定义1、斜树2、满二叉树3、完全二叉树4、二叉排序树5、平衡二叉树&#xff08;AVL树&#xff09;6、红黑树 6.2.2 二叉树的性质6.…

通用大模型 vs 垂直大模型:谁将赢得AI战场?

引言 在人工智能领域&#xff0c;大模型的快速发展引发了广泛的关注和讨论。大模型&#xff0c;尤其是基于深度学习和海量数据训练的模型&#xff0c;已经在多个领域展现出强大的能力。从自然语言处理、图像识别到自动驾驶和医疗诊断&#xff0c;AI大模型正深刻改变着我们的生…

基于二自由度汽车模型的汽车质心侧偏角估计

一、质心侧偏角介绍 在车辆坐标系中&#xff0c;质心侧偏角通常定义为质心速度方向与车辆前进方向的夹角。如下图所示&#xff0c;u为车辆前进方向&#xff0c;v为质心速度方向&#xff0c;u和v之间的夹角便是质心侧偏角。 质心侧偏角的作用有如下三点&#xff1a; 1、稳定性…

SVN笔记-SVN安装

SVN笔记-SVN安装 1、在windows下安装 SVN 1、准备svn的安装文件 下载地址&#xff1a;https://sourceforge.net/projects/win32svn/ 2、下载完成后&#xff0c;在相应的盘符中会有一个Setup-Subversion-1.8.17.msi的文件&#xff0c;目前最新的版本是1.8.17&#xff0c; 这里…

opencv4.5.5 GPU版本编译

一、安装环境 1、opencv4.5.5 下载地址&#xff1a;https://github.com/opencv/opencv/archive/refs/tags/4.5.5.ziphttps://gitee.com/mirrors/opencv/tree/4.5.0 2、opencv-contrib4.5.5 下载地址&#xff1a;https://github.com/opencv/opencv_contrib/archive/refs/tags/4…

Python中的数据可视化:从基础图表到高级可视化

数据可视化是数据分析和科学计算中不可或缺的一部分。它通过图形化的方式呈现数据&#xff0c;使复杂的统计信息变得直观易懂。Python提供了多种强大的库来支持数据可视化&#xff0c;如Matplotlib、Seaborn、Plotly等。本文将从基础图表入手&#xff0c;逐步介绍如何使用这些库…

【第十一章:Sentosa_DSML社区版-机器学习之分类】

目录 11.1 逻辑回归分类 11.2 决策树分类 11.3 梯度提升决策树分类 11.4 XGBoost分类 11.5 随机森林分类 11.6 朴素贝叶斯分类 11.7 支持向量机分类 11.8 多层感知机分类 11.9 LightGBM分类 11.10 因子分解机分类 11.11 AdaBoost分类 11.12 KNN分类 【第十一章&…

Java语言程序设计基础篇_编程练习题***18.33 (游戏:骑士旅途的动画)

目录 ***18.33 (游戏:骑士旅途的动画) 习题思路 代码示例 动画演示 ***18.33 (游戏:骑士旅途的动画) 为骑士旅途的问题编写一个程序&#xff0c;该程序应该允许用户将骑士放到任何一个起始正方形&#xff0c;并单击Solve按钮&#xff0c;用动画展示骑士沿着路径的移动&…

深度学习之表示学习 - 贪心逐层无监督预训练篇

引言 在人工智能的浩瀚星空中&#xff0c;深度学习以其强大的数据处理与模式识别能力&#xff0c;成为了一颗璀璨的明星。而表示学习&#xff0c;作为深度学习的核心基石之一&#xff0c;正引领着这一领域不断突破边界。表示学习旨在将原始数据转换为更加抽象、更有意义的特征…

leetcode第二十六题:删去有序数组的重复项

给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k &#xff0c;你…

Rasa对话模型——做一个语言助手

1、Rasa模型 1.1 模型介绍 Rasa是一个用于构建对话 AI 的开源框架&#xff0c;主要用于开发聊天机器人和语音助手。Rasa 提供了自然语言理解&#xff08;NLU&#xff09;和对话管理&#xff08;DM&#xff09;功能&#xff0c;使开发者能够创建智能、交互式的对话系统。 1.2…

Apache Iceberg 数据类型参考表

Apache Iceberg 概述-链接 Apache Iceberg 数据类型参考表 数据类型描述实例方法注意事项BOOLEAN布尔类型&#xff0c;表示真或假true, false用于条件判断&#xff0c;例如 WHERE is_active true。确保逻辑条件的正确性。INTEGER32位有符号整数42, -7可用于计算、聚合&#xf…

【系统架构设计师】专题:中间件技术

更多内容请见: 备考系统架构设计师-核心总结目录 文章目录 一、中间件概述二、中间件特点三、中间件的分类四、中间件产品介绍一、中间件概述 中间件(middleware) 是基础软件的一大类,属于可复用软件的范畴。顾名思义,中间件处在操作系统、网络和数据库之上,应用软件的下层…