Promise

Promise就是ES6新增的一个用于解决异步编程的方案。以前,我们在处理异步的时候,都是在回调函数内做处理的。比如Ajax请求,是在success属性里面做异步处理的,那么如果在一个请求中需要执行读个异步请求,第二个请求是依赖于第一个请求的结果,这样就导致代码嵌套很深,可读性差、很难维护并且难以复用。

那么Promise正好可以解决这样的问题,Promise有3种状态:pending、fulfilled和rejected。Promise在创建阶段是属于pending状态,接着状态只能有两种一个数fulfilled或者rejected,状态改变后就不能再发生变化了,例如:

const promise = new Promise((resolve, rejected) => {// 异步请求处理if (/异步请求/) {resolve();} else {rejected();}
})

异步请求成功,则执行resolve函数,否则执行rejected函数,resolve和rejected函数可以传参数,作为后面.then函数或者catch函数的数据源。

Promise在创建后立即调用,然后等待执行resolve或者是rejected函数来确定Promise的最终状态,比如下面代码:

const promise = new Promise((resolve, rejected) => {console.log("Promise");resolve();
})promise.then(() => {console.log("resolve")
});console.log("hello")

结果就是Promise,hello,resolve。因为Promise创建后会立即执行,输出Promise;然后是执行resolve函数,这样就会触发then函数里面的回调函数,但是它需要等待当前线程代码执行完毕后再执行,缩回跳过,先执行后面的代码,输出hello,最后执行then的回调函数,输出resolve。

then函数,返回的是一个Promise对象实例,所以可以通过链式调用then函数,在上一个then函数内return的值是下一个then函数接收的数据,比如:

const promise = new Promise((resolve, rejected) => {resolve(1);
})promise.then((res) => {console.log(res);return 2;
}).then(res => {console.log(res);return 3;
}).then(res => {console.log(res)
})

结果就是一次打印1,2,3。这样就是可以解决异步回调地狱的问题。

catch函数,是Promise执行失败的回调。如果我们在Promise中手动抛出一个异常,来测试catch函数,代码如下:

const promise1 = new Promise((resolve, rejected) => {try {throw new Error("测试");} catch (error) {rejected(error)}
})promise1.catch(err=>{console.log(err); // Error: 测试
})

然而Promise在执行中,如果出现异常就会自动抛出,这样上面的代码可以改为:

const promise1 = new Promise((resolve, rejected) => {throw new Error("测试");
})promise1.catch(err=>{console.log(err); // Error: 测试
})

但是需要注意,Promise的状态一旦变味fulfilled成功状态,然后再抛出异常,是不能触发catch的,因为前面已经说过了Promise的状态只要发生变化后就不能再次更改。

Promise静态方法

Promise.all()函数

将多个Promise对象实例包装成为一个Promise实例,参数是一个数组,这个Promise的状态是由所有传入Promise对象来决定,当所有的Promise的状态为fulfilled,这个新的Promise的状态才是fulfilled状态,如果有一个promise的状态为rejected,那么这个新Promise的状态就是reject。

现在使用一段代码来理解上面的描述:

const p1 = new Promise((resolve, reject) => {resolve("success")
})const p2 = new Promise((resolve, reject) => {resolve(1)
})const p = Promise.all([p1, p2]);
p.then(res => {console.log(res);
}).catch(err => {console.log(err)
})
// [ 'success', 1 ]

如果p1,p2中已经定义了对应的catch,当有一个promise状态变为reject的话,promise.all不会触发catch函数了,比如:

const p1 = new Promise((resolve, reject) => {resolve("success")
}).then(res => res).catch(err => err)const p2 = new Promise((resolve, reject) => {throw new Error("报错")
}).then(res => res).catch(err => err)const p = Promise.all([p1, p2]);
p.then(res => {console.log(res)
}).catch(err => {console.log(err)
})
// [ 'success',  Error: 报错 ]
Promise.race 函数

通过race方法来合并多个promise,那么这个promise状态是最先更新状态的promise的状态,比如:

const p1 = new Promise((resolve, reject) => {}).then(res => res).catch(err => err)const p2 = new Promise((resolve, reject) => {reject("失败了")
}).then(res => res).catch(err => err)
const race = Promise.race([p1, p2]);
race.then(res => {console.log(res)
}).catch(err => {console.log(err)
}) // 失败了
Promise.any函数

传入一个可迭代的参数,如数组。
结果为:
1、所有promise状态都为成功,返回的是第一个promise的成功状态

//1.获取轮播数据列表function getBannerList() {return new Promise((resolve, reject) => {resolve('banner')})
}//2.获取店铺列表function getStoreList() {return new Promise((resolve, reject) => {resolve('store')})
}//3.获取分类列表function getCategoryList() {return new Promise((resolve, reject) => {resolve("失败了")})
}function initLoad() {Promise.any([getBannerList(), getStoreList(), getCategoryList()]).then(res => {console.log(res)}).catch(err => {console.log(err)})}
initLoad(); // banner

2、有一个promise的状态为失败,那么就返回第一个状态为成功的promise:

//1.获取轮播数据列表function getBannerList() {return new Promise((resolve, reject) => {reject('banner')})
}//2.获取店铺列表function getStoreList() {return new Promise((resolve, reject) => {resolve('store')})
}//3.获取分类列表function getCategoryList() {return new Promise((resolve, reject) => {resolve("失败了")})
}function initLoad() {Promise.any([getBannerList(), getStoreList(), getCategoryList()]).then(res => {console.log(res)}).catch(err => {console.log(err)})}
initLoad(); // store

3、所有promise状态为失败的,那么返回的是[AggregateError: All promises were rejected]:

//1.获取轮播数据列表function getBannerList() {return new Promise((resolve, reject) => {reject('banner')})
}//2.获取店铺列表function getStoreList() {return new Promise((resolve, reject) => {reject('store')})
}//3.获取分类列表function getCategoryList() {return new Promise((resolve, reject) => {reject("失败了")})
}function initLoad() {Promise.any([getBannerList(), getStoreList(), getCategoryList()]).then(res => {console.log(res)}).catch(err => {console.log(err)})}
initLoad(); // [AggregateError: All promises were rejected]

JavaScript:Promise进阶知识相关推荐

  1. JavaScript 进阶知识 - Ajax篇

    Ajax 前言 前面我们已经学习了js基础知识和一些简单的特效,基本上已经能够写出一个带有特效的静态页面了,为什么还要称之为静态页面呢?因为网页里的数据都是写死的,真正的工作中,我们是要通过Ajax技 ...

  2. ES6 JavaScript Promise的感性认知

    ES6 JavaScript Promise的感性认知 by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu. ...

  3. 谷歌博客:彻底弄懂JavaScript Promise

    来自谷歌博客的一篇文章详细的解释了为什么Promise这么受欢迎.它用在哪些地方,具体的用法有哪些,怎么样才能用好它.读此文章,让我彻底的深入了解了Promise的相关知识及其使用方法.以下为原文 女 ...

  4. Android进阶知识:绘制流程(上)

    1.前言 之前写过一篇Android进阶知识:事件分发与滑动冲突,主要研究的是关于Android中View事件分发与响应的流程.关于View除了事件传递流程还有一个很重要的就是View的绘制流程.一个 ...

  5. 深入理解javascript函数进阶系列第一篇——高阶函数

    前面的话 前面的函数系列中介绍了函数的基础用法.从本文开始,将介绍javascript函数进阶系列,本文将详细介绍高阶函数 定义 高阶函数(higher-order function)指操作函数的函数 ...

  6. react只停留在表层?五大知识点带你梳理进阶知识

    五大知识点带你梳理react进阶知识 ✉️前言

  7. webpack入门核心知识还看不过瘾?速来围观万字入门进阶知识

    一文了解webpack入门进阶知识

  8. python的格式化输出学号_安利三个关于Python字符串格式化进阶知识

    点击蓝色"Python空间"关注我丫 加个"星标",每天一起快乐的学习 今 日 鸡 汤 名花倾国两相欢,常得君王带笑看. /前言/ 关于Python字符串格式化 ...

  9. Java工程师进阶知识完全扫盲, 太全了!!

    项目简介 本期介绍的开源项目名称叫做:advanced-java 中文名:互联网 Java 工程师进阶知识完全扫盲,该项目主要是为Java开发工程师提供进阶知识讲解,从而提升Java工程师技术与能力! ...

最新文章

  1. GDCM:排序图片的测试程序
  2. Django中的认证与权限 源码剖析
  3. 数据结构-栈1-顺序存储
  4. ES2019 的新功能 flat()
  5. ofo悄然搬离中关村,联合创始人出走,千万用户的押金还能退回来吗?
  6. 高薪诚聘项目经理,架构师,高级工程师,工程师,网页设计师
  7. RabbitMQ学习之Work Queues(2)
  8. 3个阶段 项目征名_中资企业新签的3个海外项目开工
  9. 简单的三步教你下载PyCharm汉化插件,让你学习Python事功半倍
  10. 主流开源 BI 产品对比
  11. C语言 斐波那契数列
  12. 免费的视频格式转换器哪个最好用呢?
  13. oracle nologging append 注意
  14. phpmywind 解决多语言版本 导航调取问题-5.6之前版本
  15. 好佳居窗帘十大品牌-窗帘这样搭才好看
  16. RepMet: Representative-based metric learning for classification and few-shot object detection
  17. 硬盘IOPS与读写速度
  18. OpenCV打开摄像头并显示图像(C++、Python)
  19. AlphaGo之后又来了AlphaStar,这个更厉害。。。
  20. oracle hm,Oracle 11g 新特性 – HM(Hang Manager)简介

热门文章

  1. Mysql- --DQl语句(select数据查询语言,多表查询,View试图)linux常用(重点)
  2. 企业抖音蓝V怎么认证?申请流程是怎样的?需要具备哪些条件?
  3. poj1144 - tarjan求割点
  4. 2.1.2笼形天线、V形对称天线、电视发射天线
  5. PHP导出基类(PHPExcel,PhpSpreadsheet)
  6. 码云最火爆开源项目 TOP 50,你都用过哪些?
  7. 80后男人的脱单技巧
  8. Ubuntu18.04+KinectV1(XBOX360)+ORB_SLAM2
  9. 用 Python 实现资本资产定价模型
  10. 使用AVFoundation完成照片拍摄存储相册, 开启关闭闪光灯, 切换摄像头