JavaScript ES6 promiss的理解。
本着互联网的分享精神,我将我对promise的理解分享给大家。
JavaScript ES6的promise方法主要应用在处理异步函数返回的结果,注意他不是将异步函数转换为同步函数,而是等异步函数有结果时在调用相应的方法进行处理。
promise有以下方法
then() - 它最多需要有两个参数,第一个是成功后调用的方法,第二个是失败后调用的方法。
catch() - 失败后调用的方法,他与then方法的失败后调用的方法类似,但是使用上有些区别,等下我会用案例讲解。
all() - 接收一个数组作为参数,数组内可填写异步函数,当所有的异步函数都执行完后,会返回一个promise执行后的数组。但是有一点需要注意的是,入过参数内有一个方法报错那么他就会报错,并不会返回结果。
race() - 他与all的方法类似也接受一个数组作为参数(也是如如果数组内有一个方法报错那么他将会报错,不会返回结果),但是有一点不同的是只返回一个结果,那就是哪个哪个函数最先执行完成返回的哪个结果。
resolve() - 和then的第一个参数一样,返回一个promise成功后调用方法。
reject() - 和then的第二个参数一样,返回一个promise失败后调用的方法。
万恶的异步套回调。
本案例中我使用定时器模拟ajax服务器异步请求。
- function Fun(a, b, cb) {
- setTimeout(function () {
- cb(a + b)
- }, 1000)
- }
- Fun(1, 2 ,function (result) {
- console.log(result)
- });
- console.log(5); // 此时会先输出5在输出3
在复杂一点的案例肯定是回调套回调,这样做肯定是没有错代码也会执行,但是逻辑上不是很清晰。
- function Fun(a, b, cb) {
- setTimeout(function () {
- cb(a + b)
- }, 1000)
- }
- Fun(1, 2, function (result) {
- if (result > 1) {
- Fun(result, 2, function (result) {
- Fun(result, 3, function (result) {
- console.log('完成', result)
- })
- })
- }
- });
- console.log(5); // 此时会先输出5在输出 完成 8
使用promise方法重写上面的案例- then的使用
- function Fun(a, b) {
- return new Promise(function (resolve, reject) {
- setTimeout(function () {
- resolve(a + b)
- }, 1000)
- })
- }
- Fun(1, 2)
- .then(function (result) {
- if (result > 1) {
- return Fun(result, 2)
- }
- })
- .then(function (result) {
- if (result > 1) {
- return Fun(result, 3)
- }
- }).then(function (result) {
- console.log('完成', result)
- });
使用then方法处理错误失败
then的第一个参数是处理Promise成功后使用的方法,第二个参数是Promise处理失败后的方法,下面的案例我将会模拟错误。
如果Fun函数内传入的参数不是number类型,则触发then方法的错误处理函数,也就是第二个函数,当然第一个函数就不会执行了。
- function Fun(a, b) {
- return new Promise(function (resolve, reject) {
- if (typeof a !== 'number' || typeof b !== 'number') {
- reject(new Error('no number'))
- }
- setTimeout(function () {
- resolve(a + b)
- }, 1000)
- })
- }
- Fun(1, '1')
- .then(function (result) {
- if (result > 1) {
- return Fun(result, 2)
- }
- }, function (err) { //这个方法将会被执行,因为报错了么,很好理解吧
- console.log(err )
- })
- .then(function (result) {
- console.log('第二个then'); //输出 第二个then 如果第一个then中的错误方法运用的妥当,对这里是不会有影响的,但是我并没有做相应的处理 只是输出了err, result返回的是undefined,if中的方法也就不会执行了。
- if (result > 1) {
- return Fun(result, 3)
- }
- });
使用 catch捕获错误 - catch方法的使用
then方法是从上向下运行,运行的中如果有发生错误的那么then方法就会在发生错误哪里停止运行,并且调用错误方法。注意:他与then的方法不同,then的处理机制处理完会继续向下执行,而catch却不会,会跳过未执行的then直接进入catch
- function Fun(a, b) {
- return new Promise(function (resolve, reject) {
- if (typeof a !== 'number' || typeof b !== 'number') {
- reject(new Error('no number'))
- }
- setTimeout(function () {
- resolve(a + b)
- }, 1000)
- })
- }
- Fun(1, 1)
- .then(function (result) {
- if (result > 1) {
- console.log(1) // 1正常输出。
- return Fun(result, '2') //这里2不是number类型.
- }
- })
- .then(function (result) { // 由于上面传入的参数不是number类型,这里的then 就会调用错误处理,也就是说会执行catch方法。
console.log(2) // 不会执行- if (result > 1) {
- return Fun(result, 3)
- }
- })
- .then(function (result) {
console.log(3) // 不会执行- console.log('完成', result)
- })
- .catch(
- function (err) {//会被执行 no number
- console.log(err)
- }
- );
还有一种情况主动抛出异常被catch捕获
- function Fun(a, b) {
- return new Promise(function (resolve, reject) {
- if (typeof a !== 'number' || typeof b !== 'number') {
- reject(new Error('no number'))
- }
- setTimeout(function () {
- resolve(a + b)
- }, 1000)
- })
- }
- Fun(1, 1)
- .then(function (result) {
- if (result > 1) {
- if (result === 2) {
- throw new Error('我要抛出错误因为我任性' + result) //主动抛出异常
- }
- console.log(1) 。
- return Fun(result, 2)
- }
- }
- )
- .then(function (result) {
- console.log(2)
- if (result > 1) {
- return Fun(result, 3)
- }
- })
- .then(function (result) {
- console.log(3)
- console.log('完成', result)
- })
- .catch(function (err) { // 我要抛出错误因为我任性2
- console.log(err)
- });
如果使用catch和then的第二个参数同时捕获参数会怎么样呢?
如果then方法有第二个参数那么catch就不会执行,就会执行自己的第二个参数。可以将catch理解为接盘侠,如果then没有处理错误的方法,那么catch内的方法就会执行,如果同时没有then的第二个方法和catch那么就不会报错,因为压根就没有错误的处理机制那么就不会报错了。
- function Fun(a, b) {
- return new Promise(function (resolve, reject) {
- if (typeof a !== 'number' || typeof b !== 'number') {
- reject(new Error('no number'))
- }
- setTimeout(function () {
- resolve(a + b)
- }, 1000)
- })
- }
- Fun(1, '1')
- .then(function (result) {
- if (result > 1) {
- return Fun(result, 2)
- }
- }, function (err) { //执行 输出 no number +12
- console.log(err + '12')
- })
- .then(function (result) {
- console.log('第二个then'); // 执行输出 第二个then
- if (result > 1) { //这里不会执行因为没有result 因为result 是undefined 如果在第一个then的处理方法内处理的妥当这里就可以执行。
- return Fun(result, 3)
- }
- })
- .catch(function (err) { //这里不会执行,因为每个then有自己的处理方式,所以catch就不会执行。
- console.log(err + '我是catch的错误处理')
- });
all和race方法的使用
这种方法在我们日常的项目中很常见,但是这种代码使用起来过于繁琐,那么那有没有更好的方法呢?
- function Fun(a, b) {
- return new Promise(function (resolve, reject) {
- if (typeof a !== 'number' || typeof b !== 'number') {
- reject(new Error('no number'))
- }
- setTimeout(function () {
- resolve(a + b)
- }, 1000)
- })
- }
- let resultList = [];
- Fun(1, 2)
- .then(function (result) {
- resultList.push(result);
- return Fun(2, 3)
- })
- .then(function (result) {
- resultList.push(result)
- console.log(resultList)
- });
使用all方法实现上面的案例,
all方法接收一个数组作为参数,数组内是方法,all会按照先后顺序返回一个执行后的数组。
- function Fun(a, b) {
- return new Promise(function (resolve, reject) {
- if (typeof a !== 'number' || typeof b !== 'number') {
- reject(new Error('no number'))
- }
- setTimeout(function () {
- resolve(a + b)
- }, 1000)
- })
- }
- var promise = Promise.all([Fun(1, 2), Fun(2, 3)]);
- promise.then(function (resule) {
- console.log(resule) //输出 3 5
- });
race方法的使用
race方法使用和all方法类似,但是返回结果不同,all方法返回全部结果,race返回的是最先被执行完成那个函数的结果。注意:race接收参数的数组内,如果有一个方法报错,那么就不会返回结果。
- function Fun(a, b ,time) {
- return new Promise(function (resolve, reject) {
- if (typeof a !== 'number' || typeof b !== 'number') {
- reject(new Error('no number'))
- }
- setTimeout(function () {
- resolve(a + b)
- }, time)
- })
- }
- var promise = Promise.race([Fun(1, 2,1000), Fun(2, 3,200)]);
- //race 那个结果先被得到那么就会返回第一个得到的结果、但是如果整体有一个是错误的,那么就会抛出异常而不会得到结果。
- promise.then(function (resule) {
- console.log(resule) //输出5
- });
reject和resolve的使用
reject返回的事一个抛出异常错误的方法。所以then的第二个函数或者是catch会被执行。
- var promise = Promise.reject("我要抛出错误");
- promise.then(function (reason) {
- // 未被调用
- console.log('reason')
- }, function (reason) {
- console.log(reason);//执行,因为reject就是抛出异常的方法。
- });
resolve返回的事一个正常执行的方法,所以then的第一个函数会被执行。
- var promise = Promise.resolve("我是会被执行的")
- promise.then(function (value) {
- console.log(value); // "我是会被执行的"
- }, function (value) {
- // 不会被调用
- console.log(value)
- });
JavaScript ES6 promiss的理解。的更多相关文章
- JavaScript ES6 Promiss对象
说明 Node.js中,以异步(Async)回调著称,使用了异步,提高了程序的执行效率,但是,代码可读性较差的. 假如有几个异步操作,后一个操作需要前一个操作的执行完毕之后返回的数据才能执行下去,如果 ...
- JavaScript es6 class类的理解。
本着互联网的分享精神,在本篇文章我将会把我对JavaScript es6 class类的理解分享给大家. JavaScript 类主要是 JavaScript 现有的基于原型的继承的语法糖. 类语法 ...
- JavaScript中的闭包理解
原创文章,转载请注明:JavaScript中的闭包理解 By Lucio.Yang 1.JavaScript闭包 在小学期开发项目的时候,用node.js开发了服务器,过程中遇到了node.js的第 ...
- 前端周报:前端面试题及答案总结;JavaScript参数传递的深入理解
1.2017前端面试题及答案总结 |掘金技术征文 "金三银四,金九银十",用来形容求职最好的几个月.但是随着行业的饱和,初中级前端er就业形势不容乐观. 行业状态不可控,我们能做的 ...
- JavaScript ES6中,export与export default
自述: 本来是对new Vue()和export default比较懵的,查了一下,发现我理解错了两者的关系,也没意识到export与export default的区别,先简单的记录一下基本概念,后续 ...
- 转:对JavaScript中闭包的理解
关于 const let var 总结: 建议使用 let ,而不使用var,如果要声明常量,则用const. ES6(ES2015)出现之前,JavaScript中声明变量只有 ...
- JavaScript ES6中export、import与export default的用法和区别
前言 相信很多人都使用过export.export default.import,然而它们到底有什么区别呢? 在看他们之间的区别之前,我们先来看看它们的用法. ES6 import和export的用法 ...
- 现代JavaScript—ES6+中的Imports,Exports,Let,Const和Promise
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://www.freecodecamp.org/news/learn-modern-jav ...
- 03.JavaScript 面向对象精要--理解对象
JavaScript 面向对象精要--理解对象 尽管JavaScript里有大量内建引用类型,很可能你还是会频繁的创建自己的对象.JavaScript中的对象是动态的. 一.定义属性 当一个属性第1次 ...
随机推荐
- nova network-vif-plugged 事件分析1
在创建虚机过程中,nova-compute会调用wait_for_instance_event函数(nova/compute/manage.py)进行network-vif-plugged的事件等待, ...
- “全栈2019”Java多线程第二章:创建多线程之继承Thread类
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- express 直接返回HTML文件
一般情况下用的是模板引擎,如jade: res.render('detail',{ // 使用render() #http://www.expressjs.com.cn/4x/api.html#res ...
- multiprocessor(下)
一.数据共享 展望未来,基于消息传递的并发编程是大势所趋即便是使用线程,推荐做法也是将程序设计为大量独立的线程集合,通过消息队列交换数据.这样极大地减少了对使用锁定和其他同步手段的需求,还可以扩展到分 ...
- JDK8的安装及环境配置
原文链接:https://www.cnblogs.com/chenxj/p/10137221.html 1.下载JDK: a.直接官网下载:http://www.oracle.com/: b.或百度网 ...
- 考试题T3
题意分析 这题一看没有什么思路 幸好我们机房的红太阳\(ghj1222\)切了这道题 首先我们考虑风跑一个来回之后人怎么样 就是跑了一个区间 也就是风跑了若干个来回之后 人跑了若干个区间 所以我们考虑 ...
- 第一个PSP0级
1.计划: 需求描述: 按照图片要求设计添加新课程界面.(0.5分) 在后台数据库中建立相应的表结构存储课程信息.(0.5分) 实现新课程添加的功能. 要求判断任课教师为王建民.刘立嘉.刘丹.王辉.杨 ...
- Linux文件索引节点相关概念
一. 概念 1. inode(index node)表中包含文件系统所有文件列表 一个节点 (索引节点)是在一个表项,包含有关文件的信息( 元数据 ),包括: 文件类型,权限,UID,GID 链接 ...
- BZOJ - 2500 树形DP乱搞
题意:给出一棵树,两个给给的人在第\(i\)天会从节点\(i\)沿着最长路径走,求最长的连续天数\([L,R]\)使得\([L,R]\)为起点的最长路径极差不超过m 求\(1\)到\(n\)的最长路经 ...
- 04-树5 Root of AVL Tree (25 分)
An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child sub ...