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+规范,理解 ...
随机推荐
- Wannafly模拟赛
题目描述 给出一个n * m的矩阵.让你从中发现一个最大的正方形.使得这样子的正方形在矩阵中出现了至少两次.输出最大正方形的边长. 输入描述: 第一行两个整数n, m代表矩阵的长和宽: 接下来n行,每 ...
- 【转】onConfigurationChanged
http://blog.csdn.net/xiaodongvtion/article/details/679938 转载自该文章. 注意:onConfigurationChanged事件并不是只有屏幕 ...
- 【转】netstat 命令当中的内部地址和外部地址分别代表的是什么?
RT,用自己的话解释,不要搬网上的内容.尽量可以简洁,谢谢 2015-03-07 17:41 提问者采纳 网络连接是有2方参与,自己就是“内部地址”,别人就是“外部地址”,就这么简洁. 再举个例子 ...
- 访问google的若干解决办法
据悉,海外谷歌持续被屏蔽,所有海外服务均无法访问,也无法使用google搜索,之前DNS域名污染系统攻击造成google本身故障的假象,但是现在,谷歌服务器IP的屏蔽以及443端口的屏蔽,大陆用户将无 ...
- [转]Android Studio启动时出现unable to access android sdk add-on list
转载请标明出处:http://blog.csdn.net/xx326664162/article/details/50563122 文章出自:薛瑄的博客 你也可以查看我的其他同类文章,也会让你有一定的 ...
- Django-rest-framework(二)serializers 使用
简介 初次见到serializers文件,想必大家都会感到陌生,所以,我们不妨换个词来形容他的作用,那就是django 中的Form,这样是不是感觉熟悉了一点. 实际上,serializers 的作用 ...
- c# Hash一致算法实现负载均衡
开篇吹牛..... 不吹了,因为我不擅长算法,就不胡说八道了. 现在一般的实现负载均衡,主要采用2种方法: 1.轮训 2.负载均衡算法 轮训就不说了,负载均衡现在一般采用HASH一致算法 不多说 ...
- django-auth认证模块
########django-auth认证模块######## auth模块:它是django自带的用户认证模块,帮我们解决了登陆,注册,注销,修改密码 等等一系列的操作,封装成一个个方法,方便我们使 ...
- Easyui前端、JAVA后台 上传附件
前端使用easyui框架,后台使用JAVA 的JFinal框架开发 功能描述:实现附件上传功能.文件上传路径为:../upload(上传文件夹)/身份证号/慢病编码/上传的附件. 细节要求:实现多图片 ...
- LeetCode 简单 - 路径总和(112)
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和. 说明: 叶子节点是指没有子节点的节点. 示例: 给定如下二叉树,以及目标和 sum = 22 ...