Promise异步编程模型
目录
Promise异步编程模型
Promise优点
- 规定回调的名字或顺序
- 拒绝回调地狱
- 便于捕获错误
初始化一个Promise
let promise = new Promise((resolve,reject)=>{ //最初为pending状态 if(success/*成功条件*/) resolve(data)//返回数据 //调用resolve后变为 fulfilled状态 else /*失败*/ reject(error);//返回错误 //调用reject后变为 rejected状态 })
1. Promise技术及其背景
1.1. 什么是Promise技术?
Promise是目前前端解决异步问题的统一方案。 Promise实际是一种书写回调函数的规范,为异步操作提供统一接口
1.2. 什么是异步?
异步:代码的执行不会被阻塞。
- 同步:直接拿到结果,不拿到结果不会离开
- 异步:不能直接拿到结果,异步获取结果的两种方式
- 轮询:eg.一直烦你,一直问
- 回调:eg.饭店排座,有座位再发送通知
1.3. Promise出现的背景与意义
原来的异步编程解决方案缺点显著。 原方案一:回调函数接受两个参数,eg. Node.js
fs.readFile('./1.txt',(error,data)=>{
if(error){console.log('error')return}
console.log(data.toString)
})
原方案二:搞两个回调函数
- 两个回调,每个一个参数
ajax('get','/1.json',data=>{},error=>{})
- 两个回调,封装在同一个对象里,键值为success和fail,值为回调函数
ajax('get','./1.json',{success:()=>{},fail:()=>{}})
以上两种的缺点
- 不够规范,命名(键值)不固定,success+error / success+fail / done+fail
- 回调地狱:由于必须在初始化异步操作时定义回调,只有预备好将这个短时间内存在的值作为参数的回调才能接收到它
- 难以进行错误处理: 不会触发try catch
所以要用Promise
- 规定回调的名字或顺序
- 拒绝回调地狱
- 便于捕获错误
2. Promise详解
初始化一个Promise
let promise = new Promise((resolve,reject)=>{
//最初为pending状态
if(success/*成功条件*/) resolve(data)//返回数据
//调用resolve后变为 fulfilled状态
else /*失败*/ reject(error);//返回错误
//调用reject后变为 rejected状态
})
2.1. Promise的三种状态
从待定落定为兑现/拒绝都是不可逆的
- 待定(pending)
- 兑现(fulfilled,有时候也称为“解决”,resolved)
- 拒绝(rejected)
2.2. Promise对象的.then方法
Promise.prototype.then()是为Promise实例添加处理程序的主要方法。这个 then()方法接收两个参数:onResolved 处理程序和 onRejected 处理程序。
这两个参数都是可选的,如果提供的话, 则会在期约分别进入“兑现”和“拒绝”状态时执行。
进入“兑现/拒绝”时.then方法的返回值用Promise.resolve()包装,有三种情况
- 如果resolve函数中显示返回传入值value,返回Promise.resolve(value)
- 如果resolve函数中没有显示返回值,返回Promise.resolve(undefined)
- 如果.then方法没有传入onResolved处理程序则原样返回.then前的Promise对象
2.3. Promise的注意事项
- Promise初始化的代码,是同步执行的。
- return Error(‘error!!!')不会报错,throw Error(‘error!!!')报错
- 在Promise中,返回任意一个非 promise 的值都会被包裹成 promise 对象,
- .then等方法传入非函数参数时,会忽略参数,直接传递.then前的promise
2.4. Promise对象的其他方法和Promise静态方法
- Promise对象其他方法:catch/finally
- .catch(()=>{})方法为.then(null,()=>{})的语法糖
- .finally方法无论期约在转换为解决或拒绝状态时,都会执行
- Promise静态方法:all/race
- Promise.all()静态方法创建的期约会在一组期约全部解决之后再解决。这个静态方法接收一个 可迭代对象,返回一个新期约
- Promise.race()静态方法返回一个包装期约,是一组集合中最先解决或拒绝的期约的镜像。这个方法接收一个可迭代对象,返回一个新期约
2.5. 用Promise简单封装AJAX
ajax(method, url, options)=>{
return new Promise((resolve,reject)=>{
const {success, fail} = options;
const request = new XMLHttpRequest();
request.open(method, url);
request.onreadystatechange = ()=>{
if(request.readystate === 4){
if(request.status < 400){
resolve(request.response);
}else{
reject(request);
}
}
request.send();
})
}
}
2.6. Axios:最新的AJAX库
- Promise最大的问题:不能被取消,Axios解决了,用编号解决,取消对应的AJAX(请求),Promise还是执行,但是AJAX我不要了
- 高级用法
- JSON自动处理
- 请求拦截
- 响应拦截
- 生成不同实例