Promise两个特点
1、对象的状态不受外界影响。有3种状态:Pending(进行中)、Fulfilled(已成功)和Rejected(失败)
2、一旦状态改变就不会再变,任何时候都可以得到这个结果。改变状态只有两种可能:Pending(进行中)变为Fulfilled(已成功)和Pending(进行中)变为Rejected(失败)。
Peromise缺点
1、无法取消Promise,一旦新建它就会立即执行,无法中途取消。
2、如果不设置回调函数,Promise内部抛出的出错不会反应到外部。
3、当处于Pending(进行时)状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
基本用法
Promise构造函数接受一个函数作为参数。该函数有两个函数分别时resolve和reject函数。
var promise =new Promise(function(resolve,reject){
//...som code
if(/*异步成功*/){
resolve(value)
}else{
reject(error)
}
});
- resolve函数作用,将Promise对象状态从Pending(进行中/未完成)变为Resolved(成功),异步成功调用把异步操作的结果作为参数传递。
- reject函数作用,将Promise对象状态从Pending(进行中/未完成)变为Rejected(失败),异步成功调用把异步操作的错误作为参数传递。
Promise实例解释
1、Promise实例生成后,可以使用then分别指定Resolved状态和Rejected状态回调。
promise.then(function(value){
//success
},function(error){
//failure
}
2、then可以接受两个回调函数参数。第一个回调函数是Promise对象状态变为resolved(成功)调用,第二个是Promise对象变为Rejeced调用,第二个函数可以不调用。
function timeout (ms) {
return new Promise((resolve,reject) => {
setTimeout(resolve,ms,'done);
})
}
timeout(100).then((value) => {
console.log(value)
})
/*
timeout方法返回一个人Promise实例,表示一段时间以后才会发生结果。
过了指定的时间以后,Promise实例状态百年未resolved就会触发then方法绑定的回调函数。
*/
3、Promise新建后就会立即执行
let promise =new Promise(function(resolve,reject){
console.log('Promise');
resolve();
});
promise.then(function(){
console.log('Resolved.');
});
console.log('hi!');
//Promise
//hi
//Resolved
Promise新建后会立即执行,所以首先输出的是Promise。然后,then方法指定的回调函数将在当前脚本所有同步任务执行完成后才会执行斜体样式,所以Resolved最后输出。
4、异步加载图片
function loaImageAsync(url){
return new Promise(function(resolve,reject){
var image = new Image();
image.onload = function(){
resolve(image);
};
image.onerror = function(){
reject(new Error('Could not load image at '+url));
};
image.src = url;
});
}
//Promise包装一个图片加载的异步操作。如果加载成功,就会调到同resolve方法,否则吊桶reject方法
5、异步实现AJAX操作
var get JSON = function(url) {
var promise = new Promise(function(resolve,reject) {
var client = new XMLHttpRequerst();
client.open("GET",url);
client.onreadystatechange = handler;
client.resposeType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
function hadler() {
if (this.readyState !==4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusRext));
}
});
});
return promise;
};
getJSON("/posts.json").then(function(json) {
console.log('Contents: ' + json);
} function(error) {
console.error('出错了', error);
});
// getJSON 是对 XMLHttpRequest 对象的封装,用于发出一个针对JSON数据的HTTP请求,
// 并返回一个Promise对象。需要注意的是,在 gerJSON 的内部,resolve函数和 reject
// 函数调用时带有参数。
6、如果调用 resolve 函数和 reject 函数时带有参数,那么这些参数会被传递给回调函数。reject 函数的参数通常时 Error 对象的实例,表示抛出的错误;resolve 函数的参数除了正常的值外,还可能是另一个 Pomise 实例。
var p1 = new Promise(function (resolve, reject) {
//...
});
var p2 = new Promise(function (resolve,reject) {
//...
resolve(p1);
})
//1、p1和p2都是 Promose 的实例,但是p2的 resolv 的方法将p1作为参数,即一个异步操作
//的做结果是返回另一个异步操作。
//2、p1的状态就会传递给p2。就是说,p1的状态决定了p2的状态。如果p1的状态是Pending,
//那么p2的回调函数就是等待p1的状态改变,如果p1的状态是reolved或者rejected,那么
//p2回调函数立即执行。
7、事件回调
var p1 = new Promise (function (resolve,reject) {
seTimeout (() => reject(new Error('fail')), 3000)
})
var p2 = new Promise (function (resolve, reject) {
seTimrout (() => resolve(p1), 1000)
})
p2
.then(result => console.log(result))
.catch(error => console,log(error))
//Errir: fail
//p1 是一个Promise, 3秒之后变为rejected。p2 的状态在1秒之后改变,resolve方法返回
//p1。由于p2返回的是另一个Promise, 导致p2的状态无效,由p1变为rejected,触发catch
//方法指定的回调函数
//注意:调用resolve或者reject并不会终结Promise的参数函数执行
8、同步先执行
new Promise((resolve,reject) => {
resolve(1);
console.log(2);
}).then(r => {
console.log(r);
});
//2
//1
//调用resolve(1)以后,后面的 console.log(2)还是会执行,并且会首先打印出来,这是因为立
//即resolved的Promise是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。
/*一般来说,调用resolve 或者 reject以后,Promise的使命就完成,后面操作应该放到then
方法里面中。而不应该直接卸载resolve 或者 reject的后面,所以,最好在它们前面加上return
语句,这样就不会产生意外。*/
new Promise ((resolve,reject) => {
return resolve(1);
//后面的语句不会执行
console.log(2);