Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息。
一、理解promise对象
Promise对象有如下两个特点:
(2)状态一旦成型,就不会再变,且任何时候都可得到这个结果。状态值会由pending变fulfilled或rejected,这时即为resolved。
Promise的优点
有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise 对象提供统一的接口,使得控制异步操作更加容易。
Promise的缺点有如下三个缺点:
(3)当处于pending状态时,无法得知其具体发展到了哪个阶段。
二、Promise操作
promise中的then方法
const p = new Promise( (resolve,reject) =>{
setTimeout( ()=>{
resolve(' 用户数据 ')
},1000 )
} )
p.then(value=>{
console.log(value);
},reason=>{
console.log(reason);
})
Promise实例的状态发生改变时,会调用then内部的回调函数,then方法接受两个参数,第一个为resolved的状态时的回调,第二个为reject的状态的回调。
promise中的catch方法
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
//设置p对象状态为失败 并设置失败的值
reject("error");
},1000)
})
p.then(function(value){
console.log('success')
},function(reason){
console.warn(reason)
})
//结果相同 catch表示状态为失败的操作
p.catch(function(reason){
console.log(reason)
})
上述代码中p.catch与p.then的第二个函数返回结果一致,均为失败状态下的操作,Promise 对象的错误具有"冒泡"性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个 catch 语句捕获。
promise实现ajax请求
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="ad"/>
</body>
<script type="text/javascript">
var ad=document.getElementById("ad")
const p=new Promise((resolve,reject) =>{
const xhr=new XMLHttpRequest();
xhr.open("GET","https://elm.cangdu.org/v1/cities?type=hot");
xhr.send();
xhr.onreadystatechange=function(){
if(xhr.readyState===4){
if(xhr.status>=200&&xhr.status<300){
resolve(xhr.response)
}else{
reject(xhr.status)
}
}
}
})
var arr=[];
p.then(function(value){
arr=JSON.parse(value)
console.log(arr)
ad.append(arr[0].data)
},function(reason){
console.log(reason)
})
</script>
</html>
resolve 方法和 reject 方法调用时,都带有参数。它们的参数会被传递给回调函数。reject 方法的参数通常是 Error 对象的实例。
Promise.all
var p = Promise.all([p1,p2,p3]);
上面代码中,Promise.all 方法接受一个数组作为参数,p1、p2、p3 都是 Promise 对象的实例。(Promise.all 方法的参数不一定是数组,但是必须具有 iterator 接口,且返回的每个成员都是 Promise 实例。)
p 的状态由 p1、p2、p3 决定,分成两种情况。
- (1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
- (2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
// 生成一个Promise对象的数组
var promises = [2, 3, 5, 7, 11, 13].map(function(id){
return getJSON("/post/" + id + ".json");
});
Promise.all(promises).then(function(posts) {
// ...
}).catch(function(reason){
// ...
});
执行顺序
Promise同步执行,promise.then为异步操作;Promise属于JavaScript引擎内部任务,setTimeout则是浏览器API,引擎内部任务优先级高于浏览器API任务。