ES6原生提供了Promise对象,它表示未来要发生的事件,相当于一个容器,保存着异步操作的一些结果。各种异步操作都可以用同样的方法进行处理。
可以使用new来创建一个Promise对象的一个实例。
let prom = new Promise(function(resolved, rejected) {
}
Promise包含一个回调函数,有resolve和reject两个参数,如果函数在调用时执行操作正常,则会调用resolve,否则调用reject。
实例
function timeOut(ms) {
return new Promise((resolved, rejected) => {
setTimeout(() => {
resolved("success!!")
}, ms);
})
}
timeOut(2000).then((val) => {
console.log(val);
})
我们定义一个超时函数,返回一个Promise对象实例,然后我们调用它,.then()方法返回成功的返回值success。
我们可以用promise封装一个类似于Ajax的函数。
const getJSON = function(url) {
// 返回一个promise对象
return new Promise((Resolved, Rejected) => {
const xhr = new XMLHttpRequest();
// 打开网址
xhr.open('GET', url);
// 状态改变,调用函数
xhr.onreadystatechange = handler;
xhr.responseType = 'json';
xhr.setRequestHeader("Accept", 'application/json');
// 发送
xhr.send();
function handler() {
// console.log(this.readyState);
// console.log(this);
if (this.readyState === 4) {
if (this.status === 200) {
Resolved(this.response);
} else {
Rejected(new Error(this.statusText));
}
}
}
})
}
getJSON("https://api.vvhan.com/api/weather?city=北京&type=week").then(
(data) => {
console.log(data);
}, (error) => {
console.log(error);
}
)
getJSON函数返回一个promise对象实例,在这里我们new一个请求数据的对象,然后判断状态改变(进行->成功 或者 进行->失败),调用handler函数根据状态码判断数据是否获取成功再返回相应内容。
.then().catch()链式编程
// then() 方法
// then() 第一个参数是resolved回调函数,第二个参数可选Rejected状态的回调函数
// then() 返回一个新的Promise对象实例,因此可以采用链式编程,不过实际开发一般采用.catch()方法捕获异常
// getJSON("https://api.vvhan.com/api/weather?city=北京&type=week").then(
// (data) => {
// console.log(data);
// }).catch(err => {
// console.log(err);
// })
// 这里等价于.then(null, err => {})
// resolve() 将现有的任何对象转换成promise对象
let p = Promise.resolve("foo");
console.log(p);
p.then(data => {
console.log(data); // foo
})
应用:一些游戏类的素材比较多,等待图片、静态资源都加载完成才进行页面的初始化。
all()方法有一个数组作为参数,只有当数组内容状态全为成功才会被resolve,否则reject。
let promise1 = new Promise((resolve, reject) => {
});
let promise2 = new Promise((resolve, reject) => {
});
let promise3 = new Promise((resolve, reject) => {
});
let p4 = Promise.all([promise1, promise2, promise3]);
p4.then(() => {
// 三个都成功才成功
}).catch(err => {
// 有一个失败则失败
})
Promise.race([p1,p2,p3])
当p1,p2,p3状态改变时,先返回状态改变完成的。
应用:给某个异步请求设置超时时间,并且在超时后执行相应的操作。
例如在请求一个图片资源时。
function requestImg(imgSrc) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = function() {
resolve(img);
}
img.src = imgSrc;
})
}
function timeOut() {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("图片请求超时"))
}, 3000);
})
}
let src = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fbpic.588ku.com%2Felement_origin_min_pic%2F16%2F10%2F29%2F2ac8e99273bc079e40a8dc079ca11b1f.jpg&refer=http%3A%2F%2Fbpic.588ku.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1634906070&t=c93ae1e0fdaf933291962dc5726bfb9b";
Promise.race([requestImg(src), timeOut()]).then(res => {
console.log(res);
document.body.appendChild(res);
}).catch(err => {
console.log(err);
})
图片是我随便百度的一张。当requestImg()函数成功获取图片后,返回该图片,把它渲染到页面上,否则就调用timeOut()函数扔出一个错误。
看效果:
下一篇:ES6—(4)async的用法