ES6 中 Promise对象使用学习
转载请注明出处:
Promise 对象是 JavaScript 的异步操作解决方案,为异步操作提供统一接口。它起到代理作用(proxy),充当异步操作与回调函数之间的中介,使得异步操作具备同步操作的接口。Promise 可以让异步操作写起来,就像在写同步操作的流程,而不必一层层地嵌套回调函数。
promise是一种异步解决方案。
由于ajax异步方式请求数据时,我们不能知道数据具体回来的事件,所以过去只能将一个callback函数传递给ajax封装的方法,当ajax异步请求完成时,执行callback函数。
promise对象接受resolve和reject两个参数,当一个异步动作发生时,promise对象会通过resolve完成对动作成功进行解析,reject会捕获这个动作的异常。一个promise对象,通过new Promise().then()执行下一步骤操作。
axios is a promise based HTTP client for the browser and node.js。也就是说,使用axios发出请求,难免涉及promise
Promise构造函数的参数是一个函数,函数里面的代码是异步的,即Promise里面的操作,和Promise()外面的操作时异步"同时"进行的。Promise中的函数的第一个参数是回调函数,resolve用来触发then里面的代码,第二个参数是回调函数,reject用来触发catch中的代码,throw new Error();也可以触发catch,
- resolve和reject是两个回调函数,调用resolve会触发then,reject会触发catch
<script>
new Promise((resolve, reject) =>{
setTimeout(() =>{
//成功的时候调用resolve
resolve('成功data')
//失败的时候调用reject
reject('error message')
}, 1000)
}).then((data) =>{
//处理成功后的逻辑
console.log(data);//这个data 是接收的resolve参数--
}).catch((err) =>{
console.log(err);
})
</script>
Promise 链式编程方式比较
传统的链式调用编程如下:
// 传统写法
step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
// ...
});
});
});
});
使用 Promise 之后,可以简化为如下:
// Promise 的写法
(new Promise(step1))
.then(step2)
.then(step3)
.then(step4);
从上面代码可以看到,采用 Promises 以后,程序流程变得非常清楚,十分易读。注意,为了便于理解,上面代码的Promise
实例的生成格式,做了简化
Promise 对象的状态
Promise 对象通过自身的状态,来控制异步操作。Promise 实例具有三种状态。
异步操作未完成(pending)
异步操作成功(fulfilled)
异步操作失败(rejected)
上面三种状态里面,fulfilled和rejected合在一起称为resolved(已定型)。
这三种的状态的变化途径只有两种。
从“未完成”到“成功”
从“未完成”到“失败”
一旦状态发生变化,就凝固了,不会再有新的状态变化。这也是 Promise 这个名字的由来,它的英语意思是“承诺”,一旦承诺成效,就不得再改变了。这也意味着,Promise 实例的状态变化只可能发生一次。
因此,Promise 的最终结果只有两种。
异步操作成功,Promise 实例传回一个值(value),状态变为fulfilled。
异步操作失败,Promise 实例抛出一个错误(error),状态变为rejected。
Promise 构造函数
JavaScript 提供原生的Promise
构造函数,用来生成 Promise 实例。
var promise = new Promise(function (resolve, reject) {
// ... if (/* 异步操作成功 */){
resolve(value);
} else { /* 异步操作失败 */
reject(new Error());
}
});
上面代码中,Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己实现。
resolve函数的作用是,将Promise实例的状态从“未完成”变为“成功”(即从pending变为fulfilled),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去。reject函数的作用是,将Promise实例的状态从“未完成”变为“失败”(即从pending变为rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
下面是一个例子。
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done');
});
} timeout(100)
上面代码中,timeout(100)
返回一个 Promise 实例。100毫秒以后,该实例的状态会变为fulfilled
。
Promise.prototype.then()
then
方法,用来添加回调函数。
then
方法可以接受两个回调函数,第一个是异步操作成功时(变为fulfilled
状态)时的回调函数,第二个是异步操作失败(变为rejected
)时的回调函数(该参数可以省略)。一旦状态改变,就调用相应的回调函数。
var p1 = new Promise(function (resolve, reject) {
resolve('成功');
});
p1.then(console.log, console.error);
// "成功" var p2 = new Promise(function (resolve, reject) {
reject(new Error('失败'));
});
p2.then(console.log, console.error);
// Error: 失败
上面代码中,p1和p2都是Promise 实例,它们的then方法绑定两个回调函数:成功时的回调函数console.log,失败时的回调函数console.error(可以省略)。p1的状态变为成功,p2的状态变为失败,对应的回调函数会收到异步操作传回的值,然后在控制台输出。
then方法可以链式使用。
p1.then(step1)
.then(step2)
.then(step3)
.then(
console.log,
console.error
);
上面代码中,p1后面有四个then,意味依次有四个回调函数。只要前一步的状态变为fulfilled,就会依次执行紧跟在后面的回调函数。
最后一个then方法,回调函数是console.log和console.error,用法上有一点重要的区别。console.log只显示step3的返回值,而console.error可以显示p1、step1、step2、step3之中任意一个发生的错误。举例来说,如果step1的状态变为rejected,那么step2和step3都不会执行了(因为它们是resolved的回调函数)。Promise 开始寻找,接下来第一个为rejected的回调函数,在上面代码中是console.error。这就是说,Promise 对象的报错具有传递性。
小结
Promise 的优点在于,让回调函数变成了规范的链式写法,程序流程可以看得很清楚。它有一整套接口,可以实现许多强大的功能,比如同时执行多个异步操作,等到它们的状态都改变以后,再执行一个回调函数;再比如,为多个回调函数中抛出的错误,统一指定处理方法等等。
而且,Promise 还有一个传统写法没有的好处:它的状态一旦改变,无论何时查询,都能得到这个状态。这意味着,无论何时为 Promise 实例添加回调函数,该函数都能正确执行。所以,你不用担心是否错过了某个事件或信号。如果是传统写法,通过监听事件来执行回调函数,一旦错过了事件,再添加回调函数是不会执行的。
Promise 的缺点是,编写的难度比传统写法高,而且阅读代码也不是一眼可以看懂。你只会看到一堆then,必须自己在then的回调函数里面理清逻辑。
ES6 学习链接
https://es6.ruanyifeng.com/#docs/promise
ES6 中 Promise对象使用学习的更多相关文章
- ES6中Promise对象个人理解
Promise是ES6原生提供的一个用来传递异步消息的对象.它减少了传统ajax金字塔回调,可以将异步操作以同步操作的流程表达出来使得代码维护和可读性方面好很多. Promise的状态: 既然是用来传 ...
- ES6的promise对象研究
ES6的promise对象研究 什么叫promise? Promise对象可以理解为一次执行的异步操作,使用promise对象之后可以使用一种链式调用的方式来组织代码:让代码更加的直观. 那我们为什么 ...
- 教你如何使用ES6的Promise对象
教你如何使用ES6的Promise对象 Promise对象,ES6新增的一个全新特性,这个是 ES6中非常重要的一个对象 Promise的设计初衷 首先,我们先一起了解一下,为什么要设计出这么一个玩意 ...
- ES6之Promise对象学习——8个例子学会Promise
目录 Promise 立即执行 Promise 三种状态 Promise 不可逆性 链式调用 Promise.then()回调异步性 Promise中的异常 Promise.resolve() res ...
- ES6的promise对象应该这样用
ES6修补了一位Js修真者诸多的遗憾. 曾几何时,我这个小白从js非阻塞特性的坑中爬出来,当我经历了一些回调丑陋的写法和优化的尝试之后,我深深觉得js对于多线程阻塞式的开发语言而言,可能有着其太明显的 ...
- 浅谈Javascript中Promise对象的实现
https://segmentfault.com/a/1190000000684654 What? Promise是CommonJS的规范之一,拥有resolve.reject.done.fail.t ...
- ES6 - promise对象
Promise的设计初衷 我们使用ajax请求数据,得到数据后再对数据进行操作,可是有时候,对得到的数据进行操作的过程中,可能又要用到ajax请求,这时,我们的代码就变成了这样: $.ajax({ s ...
- 对于ES6中Promise的个人见解
1.js中常见的异步 JavaScript可以响应用户的一些异步交互,比如单击鼠标和按键盘等操作. let button = document.getElementById("btn&quo ...
- ES6 中 Promise
在说Promise之前我们先简单说一下什么是同步异步? 同步(Sync):所谓同步,就是发出一个功能调用时,在没有得到结果之前,该调用就不返回或继续执行后续操作. 异步(Async):异步与同步相对, ...
- ES6的Promise对象
http://es6.ruanyifeng.com/#docs/promise Promise 对象 Promise 的含义 基本用法 Promise.prototype.then() Promise ...
随机推荐
- 齐博x1.3通用栏目名称及参数调用接口
对于全站的频道可以使用下面的方法取出相应的栏目名称及参数http://qb.net/index.php/cms/wxapp.sorts.html注意,只需要把qb.net换成你的域名,cms 换成其它 ...
- etcd实现分布式锁
转载自:etcd实现分布式锁 当并发的访问共享资源的时候,如果没有加锁的话,无法保证共享资源安全性和正确性.这个时候就需要用到锁 1.需要具备的特性 需要保证互斥访问(分布式环境需要保证不同节点.不同 ...
- docker容器化业务
1.环境准备: 设备 IP地址 作用 系统版本 mysql-master 192.168.100.213 Nginx-Web服务器 Ubuntu2004 mysql-slave 192.168.100 ...
- Spring Boot:自定义 Whitelabel 错误页面
一.概述在本文中,我们将研究如何禁用和自定义 Spring Boot 应用程序的默认错误页面,因为正确的错误处理描述了专业性和质量工作. 2.禁用白标错误页面 首先,让我们看看如何通过将server. ...
- 线上Electron应用具备哪些特征?
新用户购买<Electron + Vue 3 桌面应用开发>,加小册专属微信群,参与群抽奖,送<深入浅出Electron>.<Electron实战>作者签名版. 1 ...
- 「Python实用秘技11」在Python中利用ItsDangerous快捷实现数据加密
本文完整示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/PythonPracticalSkills 这是我的系列文章「Python实用秘技」的第11 ...
- 4.mysql-进阶
1.事务 将多个操作步骤变成一个事务,任何一个步骤失败,则回滚到事务的所有步骤之前状态,大白话:要成功都成功:要失败都失败. 如转账操作,A扣钱.B收钱,必须两个步骤都成功,才认为转账成功 innod ...
- HCIE Routing&Switching之MPLS基础理论
技术背景 90年代初期,互联网流量快速增长,而由于当时硬件技术的限制,路由器采用最长匹配算法逐跳转发数据包,成为网络数据转发的瓶颈:于是快速路由技术成为当时研究的一个热点:在各种方案中,IETF确定了 ...
- java 定时开始执行程序
package com.zx.ps.web.gzdb; import java.util.Calendar; import java.util.Date; import java.util.Timer ...
- 处理get请求中文乱码tomcat请求
修改tomcat中server配置:添加 URIEncoding="UTF-8" <Connector port="8090" protocol=&quo ...