Promise关键知识
异步是ES6中使用频率最高的特性之一,也是面试中经常会被问到的问题,特此整理了相应的笔记
一、Promise的三种状态
pending-异步操作没有结束
fulfilled-异步操作已成功结束,最常见的就是在promise对象中返回resolve()
rejected-异步操作未成功,可能是有错误等,最常见的就是在promise对象中返回reject()
二、Promise的几大特性
1.立即执行特性
当实例化了一个Promise对象时,作为Promise参数传入的函数是会被立即执行的,只是其中执行的代码可以是异步代码。
特别需要注意的是,不能理解为调用.then()时Promise参数中的函数代码才开始执行
var p = new Promise(function(resolve, reject){
console.log("create a promise");
resolve("success");
});
p.then(function(value){
console.log(value);
});
console.log("after new Promise");
控制台输出结果
"create a promise""after new Promise""success"var p2 = new Promise(function(resolve, reject){
resolve("success");
resolve("suceess2");
});
p2.then(function(value){ console.log(value);});控制台输出的结果是sucess而不是sucess2
4.链式调用
- Promise对象出现的目的就是避免回调嵌套,避免回调嵌套的手段就是使用链式调用。链式调用的实现原理实现中很简单,就是在每个方法中返回一个相同类型的对象。
- 不管是then()还是catch,不管使不使用return最终都会返回一个新的Promise实例。
- 没有return时默认返回一个状态为fulfilled的对象,如果在then中抛出异常则返回一个rejected状态的对象;
- 使用return时可以返回一个指定状态的Promise实例,也可以返回为普通值,当返回的是普通值时,实际上JS引擎会进行包装
var p = new Promise(function(resolve, reject){
resolve(1);
});
p.then(function(value){ //第一个then
console.log(value);
return value*2;
}).then(function(value){ //第二个then
console.log(value);
}).then(function(value){ //第三个then
console.log(value);
return Promise.resolve('resolve');
}).then(function(value){ //第四个then
console.log(value);
return Promise.reject('reject');
}).then(function(value){ //第五个then
console.log('resolve: '+ value);
}, function(err){
console.log('reject: ' + err);
})
- then中的Promise,必须在then内部再次使用then或catch进行处理,不然外层的then或catch无法捕获到状态
var p = new Promise(function(resolve, reject){
setTimeout(resolve('我是在then里调用的'),50)
});
var p2=function(){
return new Promise(function(resolve, reject){
setTimeout(resolve('放在第一个then中执行'),50)
});
}
p.then(function(value){
console.log('第一个then')
p2()
})
.then(()=>{
console.log('第二个then语句')
})
.catch((e)=>{
console.log(e)
})
上面的代码在p的第一个then中又调用了一个Promise-p2,此时p2没有没用then()或catch(),因此该then方法直接把控制权转给了后面的then或catch,控制台输出的结果如下
---第一个then
---第二个then
当我们把p2()改成p2().then((e)=>console.log(e))时,最外面一层的第二个then会进行等待:
---第一个then
---放在第一个then中执行
---第二个then
三、resolve和reject中的返回值是Promise类型对象时的处理机制
既可以在执行器中使用resolve(xxx)和reject(xxx),也可以使用Promise.resolve(xxx)和Promise.reject(xxx)来返回对象的执行状态,如果返回值是一个Promise类型的对象时情况比较有趣。
如果xxx是一个Promise类型,resolve(xxx)或Promise.resolve(xxx)会等待xxx的执行状态,并把XXX返回的状态做为对象的最终状态。
var p2 = new Promise(function(resolve, reject){
resolve(Promise.reject('reject')); //resolve中是一个执行失败的状态,因此p2的状态为rejected
});
p2.catch((err)=>console.log(err))
reject(xxx)或Promise.reject(xxx)则相对简单粗暴,直接把对象的状态变为rejected,不会根据XXX的执行结果来改变自身状态
var p2 = new Promise(function(resolve, reject){
reject(Promise.resolve('resolve'));
});
p2.catch((e)=>{
console.log(e)
})
var p3=Promise.reject(Promise.resolve('成功状态'))
p3.catch((e)=>{
console.log(e)
})
四、Promise中的错误
1.既可以使用throw语句,也可以使用reject,代码如下:
var p = new Promise(function(resolve, reject){
throw new Error('显示抛出一个错误')
//上面的代码等同于
try{
throw new Error('显示抛出一个错误')
}
catch(ex){
reject(ex)
}
});
2.抛出的错误可以使用then(null,(err)=>{...})也可以使用.catch((err)=>{})来捕获,当使用链式调用时,后面的catch可以捕获前面的错误
var p = new Promise(function(resolve, reject){
throw new Error('显示抛出一个错误')
});
//异常处理
p.then(null,function(err){
console.log(err.message);
return Promise.reject('返回一个reject')
})
.catch((err)=>{console.log(err)})
3.es2018新增了.finally(),不管Promise实例最终返回什么状态,都可以被该方法捕获到
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
4.错误处理钩子
未使用上面的错误处理机制时,可以监听unhandledrejection事件和rejectionhandled事件来获取错误
unhandledRejection :当一个 Promise 被拒绝、而在事件循环的一个轮次中没有任何拒 绝处理函数被调用,该事件就会被触发;
rejectionHandled :若一个 Promise 被拒绝、并在事件循环的一个轮次之后再有拒绝处 理函数被调用,该事件就会被触发。
在node.js中使用process.on('xxxx', (reason, promise) => ···)来监听事件,在window中使用window.addEventListener('unhandledrejection', event =>...),浏览器的event对象有三个属性
type : 事件的名称( "unhandledrejection" 或 "rejectionhandled" );
promise :被拒绝的 Promise 对象;
reason : Promise 中的拒绝值(拒绝原因)。
Promise关键知识的更多相关文章
- iOS之UI--通讯录的实例关键知识技术点积累
通讯录的实例关键知识技术点积累 效果展示: 作为博文笔记,既然是笔记,目的是为了能够以后做这个项目能够快速上手,如果这是我下一次阅览这个博文笔记,那么我应该先空手从零开始做,需求也就是这个项目的展示效 ...
- promise 基础知识
promise 基础知识 proise:1.Promise是异步编程的一种解决方案,它有三种状态,分别是pending-进行中.resolved-已完成.rejected-已失败2.创建实例//met ...
- 在react native用到的javascript 的一些关键知识(整理中)
发现了一个讲解javascript的好网站,分享一下,讲的非常棒! 注意,这些文章都可以选择中文进行阅读! 下面这个连接是关于prototype的: https://developer.mozilla ...
- android关键知识
1.handler 与Looper 与MessageQueue .Message关系 handler:是处理主线程(ui线程)处理耗时操作的线程,通过post message到MessageQueue ...
- Kubernetes集群部署关键知识总结
Kubernetes集群部署需要安装的组件东西很多,过程复杂,对服务器环境要求很苛刻,最好是能连外网的环境下安装,有些组件还需要连google服务器下载,这一点一般很难满足,因此最好是能提前下载好准备 ...
- 2 js的20/80关键知识
1. 2 var a = 1; undefined a 1 alert(a); undefined var b = true; var c = "Hi"; undefined al ...
- C++关键知识
<精通MFC>第一章节整理复习 //c++编程技术要点 /* //1.虚函数及多态的实现 //演示多态技术 #include <iostream> using namespac ...
- java关键知识汇总
1.泛型理解 2.java或Java框架中常用的注解及其作用详解 3.三层架构和MVC的区别 4.jdk1.8手册(提取码:bidm) 5.Rocketmq原理&最佳实践 6.spring入门 ...
- 大白话讲解Promise(二)理解Promise规范
上一篇我们讲解了ES6中Promise的用法,但是知道了用法还远远不够,作为一名专业的前端工程师,还必须通晓原理.所以,为了补全我们关于Promise的知识树,有必要理解Promise/A+规范,理解 ...
随机推荐
- 【转】eclipse 错误信息 "File Search" has encounter a problem 解决
在eclipse中使用搜索功能,发生错误: "File Search" has encounter a problem 仔细看了一下自动跳出的错误日志(Error Log),发现: ...
- java 注解annotation的使用,以及反射如何获取注解
一.注解基本知识 1.元注解 元注解是指注解的注解.包括 @Retention @Target @Document @Inherited四种. 1. Annotation型定义为@interfac ...
- 一个JS对话框,可以显示其它页面,
还不能自适应大小 garyBox.js // JavaScript Document// gary 2014-3-27// 加了 px 在google浏览器没加这个发现设置width 和height没 ...
- SQL模糊查询,sum,AVG,MAX,min函数
cmd mysql -hlocalhost -uroot -p select * from emp where ename like '___' -- 三个横线, - 代表字符,可以查询 三个enam ...
- Oracle 用户、授权、角色管理
Oracle 用户管理 一.创建用户的Profile文件SQL> create profile student limit // student为资源文件名FAILED_LOGIN_ATTEMP ...
- php第三节(运算符)
<?php //算术运算符 + - * / % //++ 前加加 先做加运算后座赋值运算 后加加 先做赋值运算后座加运算 //-- 前减减 先做加运算后座赋值运算 后减减 先做赋值运算后座加运算 ...
- PTA Java tips(转载)
在PTA提交Java程序需要注意如下几个要点 1. Main类与Scanner 1.1 Main类 你提交的所有程序都应该以如下形式出现 public class Main{ public stati ...
- vsftpd文件服务参数汇总和虚拟用户使用
FTP文件传输协议 FTP协议特点 基于C/S结构 双通道协议:数据和命令连接 数据传输格式:二进制(默认)和文本(w文本格式会修改文件内容) 两种模式:服务器角度 主动(PORT style):服务 ...
- MyEclipse格式化JSP代码导致Java表达式<%= %>自动换行的解决办法
MyEclipse格式化JSP代码导致Java表达式<%= %>自动换行的解决办法: 可以将Java表达式<%= %>换成EL表达式.
- /etc/fstab开机自动挂载设备配置
第一列:设备名字(路径?) 第二列:设备挂载路径(挂载到的位置) 第三列:分区格式 第四列:文件系统参数(?) 第五列:是否自动dump备份 0 不要 1 定期 2 不定期 第六 ...