ES6 Promise对象
简介
Promise对象: 代表了未来某个将要发生的事件(通常是一个异步操作)。
简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
ES6中的promise对象, 可以将异步操作以同步的流程表达出来,很好地解决了回调地狱的问题。
回调地狱:回调函数层层嵌套或者其他回调函数高耦合的现象。回调地狱如果有一个出错会影响到很多其他的部分,并且很难进行维护和二次开发。
promise对象的3个状态
- 初始化状态(等待状态):pending
- 成功状态:fullfilled
- 失败状态:rejected
使用promise的基本步骤
- 创建promise对象
- 调用promise的回调函数then()
Promise对象有以下两个特点。
- 对象的状态不受外界影响。 三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。
语法
创建一个promise对象语法如下:
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
- Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
- resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
- reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
.then
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
promise.then(function(value) {
// success
}, function(error) {
// failure
});
举个栗子
下面这个代码可以看出promise构造函数的参数是一个箭头函数,箭头函数有两个参数resolve, reject。进入这个箭头函数时候状态为“pending”
if语句判断异步操作的执行状况:
- 如果成功就执行resolve(),promise的状态会被自动修改为fullfilled。
- 如果失败就执行reject(),promise的状态会被自动修改为rejected。
if语句的结果,也就是执行了resolve()还是reject(),不论哪一个,都可以给promise.then()传递参数。promise.then(function(value) { // success}, function(error) { // failure });
如果成功,promise.then就会执行参数1的方法,如果失败,就会执行参数2的方法。
上面这段代码输出:
我在promise中写的是if(true)
那么会执行resolve()
,然后.then
就会执行第一个参数的方法,也就是输出“成功了”。
创建成功或失败的Promise对象
就是说如果你只需要处理成功结果或者只需要处理失败结果,那就可以简写。下边的写法都是等价的。
可以用then的第二个参数方法捕获错误,也可以用catch捕获错误。写法都是等价的。
补充:
promise
.then(result => {···}) //两个参数方法,前面正确后面错误
.catch(error => {···}) //一个参数方法,只处理错误
.finally(() => {···}); //一个参数方法,正确错误都可以处理,ES2018出现
promise和AJAX
正常我们写ajax是这样:
var pro = new XMLHttpRequest;
pro.open(method, url);
pro.onreadystatechange = function() {
if (pro.readyState == 4) {
if (pro.status == 200 || pro.status == 304) {
//处理成功请求
} else {
//处理失败请求
}
}
}
pro.send();
那promise怎么和ajax结合呢。只要把这段代码搬到promise的参数方法中即可。然后就可以将if语句用resolve()和reject()处理。
当然了, promise的参数可以用正常的函数,写箭头函数也可以
var ajaxPro = new Promise((resolve, reject) => {})
var ajaxPro = new Promise(function(resolve, reject) {})
举个栗子
例子中可以看到我的请求成功了。if语句进入了resolve(pro),然后将参数传给then,then就执行了resolve,输出了我请求到的结果。
ajax的原生方法fetch
下边的代码就是我把上边截图的可以改进一下,把promise封装了起来了,然后把返回的内容用JSON.parse()
转为了JavaScript的字符串。
let myUrl = "ajax/13promise.json";
//封装起来
function promise(url) {
return new Promise(function(resolve, reject) {
var pro = new XMLHttpRequest;
pro.open("GET", url);
pro.onreadystatechange = function() {
if (pro.readyState == 4) {
if (pro.status == 200 || pro.status == 304) {
resolve(pro);
} else {
reject(pro);
}
}
}
pro.send(null);
})
}
//调用
var ajaxPro = promise(myUrl);
ajaxPro.then(function(result) {
var res = JSON.parse(result.responseText);
console.log(res); //输出 {name: "promisezzz", demo: "hahahahdemo"}
}, function(err) {});
上边这段代码只是帮助理解promise而已,实际写的时候用ajax的fetch方法就好。下面给出fetch方法:
let myUrl = "ajax/13promise.json";
fetch(myUrl).then(function(result){
var res = result.json();
res.then(function(response){
console.log(response); //输出 {name: "promisezzz", demo: "hahahahdemo"}
})
})
上一篇: java多线程(五)
下一篇: MySQL MyISAM与表锁