promise介绍与基本使用
Promise是js异步编程的一种解决方案
异步编程:
1.fs 文件操作
2.数据库操作
3.AJAX
4.定时器
promise的三种状态
pending :等待状态,如正在等待网络请求
fulfilled : 满足状态,当主动回调了resolve()时,就处于该状态,并且会回调.then()
rejected : 拒绝状态,当主动回调了reject()时,就处于该状态,并且会回调.catch()
promise 的优缺点
优点:
将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数;promise提供统一的接口,控制异步操作更加容易。
缺点:
promise一旦执行,无法中途取消;若不设置回调,promise内部抛出错误,不会反应到外部,处于pending状态时,无法得知目前进展到哪一阶段。(刚刚开始还是即将完成)
简单使用
new Promise((resolve,reject) =>{
setTimeout(() =>{
resolve('Hello world')
//reject('error data')
},1000)
}).then(data =>{
console.log(data)
}).catch((err) =>{
console.log(err)
})
//也可写成
new Promise((resolve,reject) =>{
setTimeout(() =>{
resolve('Hello world')
//reject('error data')
},1000)
}).then(data =>{
console.log(data)
},err=>{
console.log(err)
})
promise的链式调用
直接通过Promise包装了一下新的数据,将Promise对象返回
Promise.resolve() :将数据包装成Promise对象,并且在内部回调了resolve函数
Promise.reject() :将数据包装成Promise对象,并且在内部回调了reject函数
new Promise((resolve,reject) =>{
setTimeout(() =>{
resolve('hello world')
},1000)
}).then(data =>{
console.log(data); //hello world
return Promise.resolve(data + '1')
}).then(data =>{
console.log(data); //hello world1
return Promise.resolve(data + '2')
}).then(data =>{
console.log(data); //hello world12
return Promise.reject(data + 'error')
}).then(data =>{
console.log(data); //这里没有输出,这部分代码不执行
return Promise.resolve(data + '3')
}).catch(data =>{
console.log(data); //hello world12error
return Promise.resolve(data + '4')
}).then(data =>{
console.log(data); //hello world123error4
})
promise API
1.Promise构造函数:Promise(excutor){}
excutor函数:执行器 (resolve,reject) =>{}
resolve函数:内部定义成功时我们调用的函数 value =>{}
reject函数:内部定义失败时我们调用的函数 reason =>{}
excutor会在Promise内部立即同步调用,异步操作在执行器中执行
2.Promise.prototype.then方法:(onResolved,onRejected) =>{}
onResolved函数:成功的回调函数 (value) =>{}
onRejected函数: 失败的回调函数 (reason) =>{}
指定用于得到成功value的成功回调和用于得到失败reason的失败回调返回一个新的promise对象
3.Promise.prototype.catch方法:(onRejected) =>{}
onRejected函数:失败的回调函数 (reason) =>{}
4.Promise.resolve方法:(value) =>{}
value:成功的数据或promise对象
返回一个成功/失败的promise对象
5.Promise.reject方法:(reason) =>{}
reason:失败的原因
返回一个失败的promise对象
6.Promise.all方法:(promises) =>{}
promises:包含n个promise的数组
返回一个新的promise对象,只有所有promise成功才成功,一个失败直接失败
7.Promise.race方法:(promises) =>{}
promises:包含n个promise的数组
返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
promise 关键问题
1.改变promise状态
resolve(value);reject(reason);抛出异常
2.一个promise指定多个成功/失败回调函数,当promise改变为对应状态时都会调用
3.改变promise状态和指定回调函数谁先谁后?
正常情况下先指定回调再改变状态,但也可以先改变状态再指定回调
先改变状态再指定回调的方法:
在执行器中直接调用reslove()/reject()
延迟更长时间调用then()
promise 自定义封装
function Promise(executor){
//添加属性
this.promiseState = 'pending';
this.promiseResult = null;
this.callbacks = [];
//保存实例对象的this值
const self = this;
//此处的resolve/reject为形参,无固定名称,与执行器中保持一致即可
function resolve(data){
//判断状态
if(self.promiseState !== 'pending') return;
//1.修改对象状态(promiseState)
self.promiseState = 'fulfilled';
//2.设置对象结果值(promiseResult)
self.promiseResult = data;
//调用成功的回调
self.callbacks.forEach(item =>{
item.onResolved(data);
})
}
function reject(data){
//判断状态
if(self.promiseState !== 'pending') return;
//1.修改对象状态(promiseState)
self.promiseState = 'rejected';
//2.设置对象结果值(promiseResult)
self.promiseResult = data;
//调用失败的回调
self.callbacks.forEach(item =>{
item.onRejected(data);
})
}
try{
//执行器函数是同步调用的
executor(resolve,reject);
}catch(e){
//修改promise的状态为失败
reject(e);
}
}
//添加then方法
Promise.prototype.then = function(onResolved,onRejected){
return new Promse((resolve,reject) =>{
//调用回调函数
if(this.PromiseState == 'fulfilled'){
try{
//获取回调函数的执行结果
let result = onResolved(this.PromiseResult);
//判断
if(result instanceof Promise){
//如果是promise类型的对象
result.then(v =>{
resolve(v);
},r =>{
reject(r);
})
}else{
//结果的对象状态为成功
resolve(result);
}
}catach(e){
reject(e);
}
}
if(this.PromiseState == 'rejected'){
onRejected(this.PromiseResult);
}
if(this.PromiseState == 'pending'){
//保存回调函数
this.callback.push({
onResolved: onResolved,
onRejected: onRejected
});
}
})
}
async 与 await
async函数是使用async关键字声明的函数。 async函数是AsyncFunction构造函数的实例, 并且其中允许使用await关键字。async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise。