什么是promise
promise
是异步编程的一种方案,解决了地狱回调的问题,是一种链式调动的方式
-
Promise
简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。 -
promise
是一个对象,从它可以获取异步操作的的最终状态(成功或失败)。 -
Promise
是一个构造函数,对外提供统一的 API,自己身上有all、reject、resolve
等方法,原型上有then、catch
等方法。
名词约定
promise
(首字母小写)对象指的是“Promise
实例对象”Promise
首字母大写且单数形式,表示“Promise
构造函数”Promises
首字母大写且复数形式,用于指代“Promises
规范”
Promise的两个特点
Promise
对象的状态不受外界影响
1)pending
初始状态
2)fulfilled
成功状态
3)rejected
失败状态
Promise
有以上三种状态,只有异步操作的结果可以决定当前是哪一种状态,其他任何操作都无法改变这个状态
Promise
的状态一旦改变,就不会再变,任何时候都可以得到这个结果,状态不可以逆,只能由 pending
变成fulfilled
或者由pending
变成rejected
使用 new 来创建一个promise对象。
Promise
接受一个「函数」作为参数,该函数的两个参数分别是resolve
和reject
。这两个函数就是就是「回调函数」
resolve
函数的作用:在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject
函数的作用:在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去
- then()方法:
then
方法就是把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数。 - catch()方法: 当执行
resolve
的回调(也就是上面 then 中的第一个参数)时,如果抛出异常了(代码出错了),那么也不会报错卡死js
,而是会进到这个catch
方法中。 - all()方法:
Promise
的all
方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。 - race()方法:
race
按字面解释,就是赛跑的意思。race
的用法与all
一样,只不过all
是等所有异步操作都执行完毕后才执行then
回调。而race
的话只要有一个异步操作执行完毕,就立刻执行then
回调。
promise简单举例
//Promise异步封装ajax
<script>
function Feach(method, ) {
let p = new Promise((resolve, reject) => {
// 手写原生ajax
let xhr = new XMLHttpRequest(); //创建ajax请求
xhr.open(method, url, true); //发起请求
xhr.send(null); //发送请求,发送的参数是空的
//异步回调函数
xhr.onreadystatechange = function () {
//readystate:请求返回五种状态
// 0(未初始化):还没有调用send()方法
// 1(载入):已调用send()方法,正在发送请求
// 2(载入完成):send()方法执行完成,已经接收全部响应内容
// 3(交互):正在解析响应内容
// 4(完成):响应内容解析完成,可以在客户端调用了
if (xhr.readyState == 4 && xhr.status == 200) {
resolve(xhr.responseText); //responseText:获取字符式的响应数据 responseXML:获取XML形式的响应数据
} else if (xhr.status == 400) {
reject('失败')
}
}
})
return p;
}
let url = "http://wthrcdn.etouch.cn/weather_mini?city=%E5%8C%97%E4%BA%AC";
Feach('get',url).then(res => {
console.log(res)
}, err => {
console.log(err)
})
</script>
<script>
//promise异步加载图片
// 创建一个函数
function requestImg(){
// 创建一个promise对象
var p= new Promise(function(resolve,reject){
// 创建一个图像对象
var img=new Image();
// 图像在页面加载完成后执行成功的回调
img.onload=function(){
resolve(img);
}
img.src="./qzone.png"
});
return p;
}
//延时函数,用于给请求计时
function timeout(){
// 创建一个promise对象,如果请求超时则执行错误的回调
var p=new Promise(function(resolve,reject){
setTimeout(()=>{
let span=documnet.createElement('span')
span.innerText='加载失败'
resolve(span);
},5000);
});
return p;
}
// promise执行一次后如果执行成功就执行then方法,否则执行catch方法
Promise.race([requestImg(),timeout()]).then(function(results){
console.log(results);
}).catch(function(reason){
console.log(reason)
});
//上面代码requestImg函数异步请求一张图片,timeout函数是一个延时5秒的异步操作,我们将他们在一起放在race中赛跑
//如果5秒内图片请求成功那么便进入then方法,执行正常的流程。
// 如果5秒内图片还未成功返回,那么则进入catch,报“图片请求超时”的信息
</script>