ES6关于Promise的用法
Node的产生,大大推动了Javascript
这门语言在服务端的发展,使得前端人员可以以很低的门槛转向后端开发。
当然,这并不代表迸发成了全栈。全栈的技能很集中,绝不仅仅是前端会写一些HTML
和一些交互,后台熟悉数据库的增删查改。
想必接触过Node的人都知道,Node是以异步(Async)回调著称的,其异步性提高了程序的执行效率,但同时也减少了程序的可读性。如果我们有几个异步操作,并且后一个操作需要前一个操作返回的数据才能执行,这样按照Node的一般执行规律,要实现有序的异步操作,通常是一层加一层嵌套下去。
为了解决这个问题,ES6提出了Promise
的实现。
含义
Promise 对象用于一个异步操作的最终完成(或失败)及其结果值的表示。简单点说,它就是用于处理异步操作的,异步处理成功了就执行成功的操作,异步处理失败了就捕获错误或者停止后续操作。
它的一般表示形式为:
new Promise(/* executor */function(resolve, reject) {if (/* success */) {// ...执行代码resolve();} else { /* fail */// ...执行代码reject();}}
);
其中,Promise中的参数executor
是一个执行器函数,它有两个参数resolve
和reject
。它内部通常有一些异步操作,如果异步操作成功,则可以调用resolve()来将该实例的状态置为fulfilled
,即已完成的,如果一旦失败,可以调用reject()来将该实例的状态置为rejected
,即失败的。
我们可以把Promise对象看成是一条工厂的流水线,对于流水线来说,从它的工作职能上看,它只有三种状态,一个是初始状态(刚开机的时候),一个是加工产品成功,一个是加工产品失败(出现了某些故障)。同样对于Promise对象来说,它也有三种状态:
pending
初始状态,也称为未定状态,就是初始化Promise时,调用executor执行器函数后的状态。fulfilled
完成状态,意味着异步操作成功。rejected
失败状态,意味着异步操作失败。
它只有两种状态可以转化,即
- 操作成功
pending -> fulfilled - 操作失败
pending -> rejected
并且这个状态转化是单向的,不可逆转,已经确定的状态(fulfilled/rejected)无法转回初始状态(pending)。
方法
Promise.prototype.then()
Promise对象含有then方法,then()调用后返回一个Promise对象,意味着实例化后的Promise对象可以进行链式调用,而且这个then()方法可以接收两个函数,一个是处理成功后的函数,一个是处理错误结果的函数。
如下:
var promise1 = new Promise(function(resolve, reject) {// 2秒后置为接收状态setTimeout(function() {resolve('success');}, 2000);
});promise1.then(function(data) {console.log(data); // success
}, function(err) {console.log(err); // 不执行
}).then(function(data) {// 上一步的then()方法没有返回值console.log('链式调用:' + data); // 链式调用:undefined
}).then(function(data) {// ....
});
在这里我们主要关注promise1.then()方法调用后返回的Promise对象的状态,是pending
还是fulfilled
,或者是rejected
?
返回的这个Promise对象的状态主要是根据promise1.then()方法返回的值,大致分为以下几种情况:
- 如果then()方法中返回了一个参数值,那么返回的Promise将会变成接收状态。
- 如果then()方法中抛出了一个异常,那么返回的Promise将会变成拒绝状态。
- 如果then()方法调用resolve()方法,那么返回的Promise将会变成接收状态。
- 如果then()方法调用reject()方法,那么返回的Promise将会变成拒绝状态。
- 如果then()方法返回了一个未知状态(pending)的Promise新实例,那么返回的新Promise就是未知状态。
- 如果then()方法没有明确指定的resolve(data)/reject(data)/return data时,那么返回的新Promise就是接收状态,可以一层一层地往下传递。
转换实例如下:
var promise2 = new Promise(function(resolve, reject) {// 2秒后置为接收状态setTimeout(function() {resolve('success');}, 2000);
});promise2.then(function(data) {// 上一个then()调用了resolve,置为fulfilled态console.log('第一个then');console.log(data);return '2';}).then(function(data) {// 此时这里的状态也是fulfilled, 因为上一步返回了2console.log('第二个then');console.log(data); // 2return new Promise(function(resolve, reject) {reject('把状态置为rejected error'); // 返回一个rejected的Promise实例});}, function(err) {// error}).then(function(data) {/* 这里不运行 */console.log('第三个then');console.log(data);// ....}, function(err) {// error回调// 此时这里的状态也是fulfilled, 因为上一步使用了reject()来返回值console.log('出错:' + err); // 出错:把状态置为rejected error}).then(function(data) {// 没有明确指定返回值,默认返回fulfilledconsole.log('这里是fulfilled态');
});
Promise.prototype.catch()
catch()方法和then()方法一样,都会返回一个新的Promise对象,它主要用于捕获异步操作时出现的异常。因此,我们通常省略then()方法的第二个参数,把错误处理控制权转交给其后面的catch()函数,如下:
var promise3 = new Promise(function(resolve, reject) {setTimeout(function() {reject('reject');}, 2000);
});promise3.then(function(data) {console.log('这里是fulfilled状态'); // 这里不会触发// ...
}).catch(function(err) {// 最后的catch()方法可以捕获在这一条Promise链上的异常console.log('出错:' + err); // 出错:reject
});
Promise.all()
Promise.all()接收一个参数,它必须是可以迭代的,比如数组。
它通常用来处理一些并发的异步操作,即它们的结果互不干扰,但是又需要异步执行。它最终只有两种状态:成功或者失败。
它的状态受参数内各个值的状态影响,即里面状态全部为fulfilled
时,它才会变成fulfilled
,否则变成rejected
。
成功调用后返回一个数组,数组的值是有序的,即按照传入参数的数组的值操作后返回的结果。如下:
// 置为fulfilled状态的情况
var arr = [1, 2, 3];
var promises = arr.map(function(e) {return new Promise(function(resolve, reject) {resolve(e * 5);});
});Promise.all(promises).then(function(data) {// 有序输出console.log(data); // [5, 10, 15]console.log(arr); // [1, 2, 3]
});
// 置为rejected状态的情况
var arr = [1, 2, 3];
var promises2 = arr.map(function(e) {return new Promise(function(resolve, reject) {if (e === 3) {reject('rejected');}resolve(e * 5);});
});Promise.all(promises2).then(function(data) {// 这里不会执行console.log(data);console.log(arr);
}).catch(function(err) {console.log(err); // rejected
});
Promise.race()
Promise.race()和Promise.all()类似,都接收一个可以迭代的参数,但是不同之处是Promise.race()的状态变化不是全部受参数内的状态影响,一旦参数内有一个值的状态发生的改变,那么该Promise的状态就是改变的状态。就跟race
单词的字面意思一样,谁跑的快谁赢。如下:
var p1 = new Promise(function(resolve, reject) {setTimeout(resolve, 300, 'p1 doned');
});var p2 = new Promise(function(resolve, reject) {setTimeout(resolve, 50, 'p2 doned');
});var p3 = new Promise(function(resolve, reject) {setTimeout(reject, 100, 'p3 rejected');
});Promise.race([p1, p2, p3]).then(function(data) {// 显然p2更快,所以状态变成了fulfilled// 如果p3更快,那么状态就会变成rejectedconsole.log(data); // p2 doned
}).catch(function(err) {console.log(err); // 不执行
});
Promise.resolve()
Promise.resolve()接受一个参数值,可以是普通的值
,具有then()方法的对象
和Promise实例
。正常情况下,它返回一个Promise对象,状态为fulfilled
。但是,当解析时发生错误时,返回的Promise对象将会置为rejected
态。如下:
// 参数为普通值
var p4 = Promise.resolve(5);
p4.then(function(data) {console.log(data); // 5
});// 参数为含有then()方法的对象
var obj = {then: function() {console.log('obj 里面的then()方法');}
};var p5 = Promise.resolve(obj);
p5.then(function(data) {// 这里的值时obj方法里面返回的值console.log(data); // obj 里面的then()方法
});// 参数为Promise实例
var p6 = Promise.resolve(7);
var p7 = Promise.resolve(p6);p7.then(function(data) {// 这里的值时Promise实例返回的值console.log(data); // 7
});// 参数为Promise实例,但参数是rejected态
var p8 = Promise.reject(8);
var p9 = Promise.resolve(p8);p9.then(function(data) {// 这里的值时Promise实例返回的值console.log('fulfilled:'+ data); // 不执行
}).catch(function(err) {console.log('rejected:' + err); // rejected: 8
});
Promise.reject()
Promise.reject()和Promise.resolve()正好相反,它接收一个参数值reason
,即发生异常的原因。此时返回的Promise对象将会置为rejected
态。如下:
var p10 = Promise.reject('手动拒绝');
p10.then(function(data) {console.log(data); // 这里不会执行,因为是rejected态
}).catch(function(err) {console.log(err); // 手动拒绝
}).then(function(data) {// 不受上一级影响console.log('状态:fulfilled'); // 状态:fulfilled
});
总之,除非Promise.then()方法内部抛出异常或者是明确置为rejected态,否则它返回的Promise的状态都是fulfilled态,即完成态,并且它的状态不受它的上一级的状态的影响。
总结
大概常用的方法就写那么多,剩下的看自己实际需要再去了解。
解决Node回调地狱的不止有Promise
,还有Generator
和ES7提出的Async
实现。
方法不在多,而在于精。
原文地址:https://segmentfault.com/a/1190000011652907
转载于:https://www.cnblogs.com/lalalagq/p/9767435.html
ES6关于Promise的用法相关推荐
- ES6之Promise基本用法
1.Promise相关概念 Promise 是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理和更强大.它由社区最早提出和实现,ES6将其写进了语言标准,统一了语法,原生提供了Prom ...
- ES6关于Promise的用法详解
Node的产生,大大推动了Javascript这门语言在服务端的发展,使得前端人员可以以很低的门槛转向后端开发. 当然,这并不代表迸发成了全栈.全栈的技能很集中,绝不仅仅是前端会写一些HTML和一些交 ...
- ES6中Promise的用法及resolve、rejected、catch、finally说明
文章目录 Promise对象的特点: Promise语法 Promise.then() Promise.catch() Promise.finally() Promise.all() Promise. ...
- ES6 — Promise基础用法详解(resolve、reject、then、catch,all,)
ES6 - Promise基础用法详解 Promise 是一个构造函数,它自身拥有all.reject.resolve这几个眼熟的方法, 原型上有then.catch等同样熟悉的方法. 所以,在开始一 ...
- 前端js进阶之ES6 Promise(承诺)用法小结笔记、详细解释(resolve,catch,catch)历史最通俗易懂的承诺
什么是Promise? 英文翻译:承诺! js里: Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有all.reject.resolve这几个方法,原型上有then.catch ...
- 【ES6】Promise用法
promise理解及使用 Promise解决的问题--异步 Promise的基本用法 异步操作拒绝及中断调用链 ES6对Promise/A+的扩展 Promise.all的扩展 Promise.rac ...
- ES6 之 Promise用法详解
promise用了这么多年了,一直也没有系统整理过.今天整理整理promise的相关东西,感兴趣的可以一起看一看.我尽量用更容易理解的语言来剖析一下promise 我准备分两篇文章来说明一下promi ...
- Promise基础用法
什么是Promise? Promise是用来处理异步的; Promise就是承诺,对未来的承诺; 所谓的Promise(承诺),里面保存着未来才会结束的事件的结果; Promise是异步编程的一种解决 ...
- 【ES6】Promise对象详解
[ES6]Promise对象详解 一.Promise对象的含义 二.Promise对象的用法 三.Promise对象的几个应用[重点] 1.时间延迟函数 2.图片异步加载 查看更多ES6教学文章: 参 ...
最新文章
- 国内高校硕博补贴大公开!(某校博士在读已经年薪 25w 了)
- angular1x初始与架构演进(四)gulp配置+OcLazyLoad中资源MD5时间轴更新
- python必须连网开发吗_Python开发,请避开这些坑!
- Prepare document for Week 2: Signaloid in Logistics
- 提高C程序效率的10种方法
- 计算机加入域 不能访问网络位置 解决办法
- 中国式创新技术“步态识别”终于来临,你大胆地走两步,我就知道你是谁
- 前端学习(2021)vue之电商管理系统电商系统之合并goodlist的分支
- 【Python】字符串反转
- linux 关联数组,Linux shell数组与关联数组的用法实例
- JAVA学习之网络编程UDP篇
- 李航——《统计学习方法》(一)
- 软件测试面试题整理(三)之工作/项目流程篇
- intel 82599网卡系统下丢失一路万兆端口
- 射频识别技术漫谈(16)——Mifare UltraLight
- Java提升反射效率
- 云计算和web服务器应用,基于云计算的Web服务选择及应用研究
- 解决WordPress文章页面无法显示的问题
- 大数据可视化是什么?
- 每日单词20110603
热门文章
- python快速编程入门教程-半小时带你快速入门Python编程,Python快速入门教程
- python代码编辑器排行榜-写 Python 哪个编辑器 / IDE 最好用?
- python可以做什么项目-适合Python 新手的5大练手项目,你练了么?
- 自学python爬虫要多久-入门Python爬虫要学习多久?
- python读取文件第n行-Python实现读取文件最后n行的方法
- python装饰器原理-Python装饰器原理
- python就业方向及工资-Python的5大就业方向,薪资诱人前景好!
- python就业方向及工资-Python的就业的方向和前景
- python使用for循环打印99乘法表-Python用for循环实现九九乘法表
- python100个必背知识-学Python必须背的42个常见单词,看看你都会吗?