概述
Promise对象: 代表了未来某个将要发生的事件(通常是一个异步操作)。
ES6中的promise对象, 可以将异步操作以同步的流程表达出来,很好地解决了回调地狱的问题(避免了层层嵌套的回调函数)。在使用ES5的时候,在多层嵌套回调时,写完的代码层次过多,很难进行维护和二次开发。
回调地狱的举例
假设买菜、做饭、洗碗都是异步的。
现在的流程是:买菜成功之后,才能开始做饭。做饭成功后,才能开始洗碗。这里面就涉及到了回调的嵌套。
ES6的Promise是一个构造函数, 用来生成promise实例。
promise对象的3个状态
-
初始化状态(等待状态):pending
-
成功状态:fullfilled
-
失败状态:rejected
使用promise的基本步骤
(1)创建promise对象
(2)调用promise的回调函数then()
代码格式如下:
let promise = new Promise((resolve, reject) => {
//进来之后,状态为pending
console.log('111'); //这一行代码是同步的
//开始执行异步操作(这里开始,写异步的代码,比如ajax请求 or 开启定时器)
if (异步的ajax请求成功) {
console.log('333');
resolve();//如果请求成功了,请写resolve(),此时,promise的状态会被自动修改为fullfilled
} else {
reject();//如果请求失败了,请写reject(),此时,promise的状态会被自动修改为rejected
}
})
console.log('222');
//调用promise的then()
promise.then(() => {
//如果promise的状态为fullfilled,则执行这里的代码
console.log('成功了');
}
, () => {
//如果promise的状态为rejected,则执行这里的代码
console.log('失败了');
}
)
代码解释:
(1)当new Promise()执行之后,promise对象的状态会被初始化为pending
,这个状态是初始化状态。new Promise()
这行代码,括号里的内容是同步执行的。括号里定义一个function,function有两个参数:resolve和reject。如下:
-
如果请求成功了,请写resolve(),此时,promise的状态会被自动修改为fullfilled。
-
如果请求失败了,请写reject(),此时,promise的状态会被自动修改为rejected
(2)promise.then()方法,括号里面有两个参数,分别代表两个函数 function1 和 function2:
-
如果promise的状态为fullfilled(意思是:如果请求成功),则执行function1里的内容
-
如果promise的状态为rejected(意思是,如果请求失败),则执行function2里的内容
另外,resolve()和reject()这两个方法,是可以给promise.then()传递参数的。如下:
let promise = new Promise((resolve, reject) => {
//进来之后,状态为pending
console.log('111'); //这行代码是同步的
//开始执行异步操作(这里开始,写异步的代码,比如ajax请求 or 开启定时器)
if (异步的ajax请求成功) {
console.log('333');
resolve('haha');//如果请求成功了,请写resolve(),此时,promise的状态会被自动修改为fullfilled
} else {
reject('555');//如果请求失败了,请写reject(),此时,promise的状态会被自动修改为rejected
}
})
console.log('222');
//调用promise的then()
promise.then((successMsg) => {
//如果promise的状态为fullfilled,则执行这里的代码
console.log(successMsg, '成功了');
}
, (errorMsg) => {
//如果promise的状态为rejected,则执行这里的代码
console.log(errorMsg, '失败了');
}
)
ajax请求的举例(涉及到嵌套的回调)
//定义一个请求news的方法
function getNews(url) {
//创建一个promise对象
let promise = new Promise((resolve, reject) => {
//初始化promise状态为pending
//启动异步任务
let request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState === 4) {
if (request.status === 200) {
let news = request.response;
resolve(news);
} else {
reject('请求失败了。。。');
}
}
};
request.responseType = 'json';//设置返回的数据类型
request.open("GET", url);//规定请求的方法,创建链接
request.send();//发送
})
return promise;
}
getNews('http://localhost:3000/news?id=2')
.then((news) => {
console.log(news);
document.write(JSON.stringify(news));
console.log('http://localhost:3000' + news.commentsUrl);
return getNews('http://localhost:3000' + news.commentsUrl);
}, (error) => {
alert(error);
})
.then((comments) => {
console.log(comments);
document.write('<br><br><br><br><br>' + JSON.stringify(comments));
}, (error) => {
alert(error);
})
网友评论