为什么需要promise,要解决回调地狱(在回调函数中嵌套回调)
promise
主要用于异步计算
可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
可以在对象之间传递和操作promise,帮助我们处理队列
Promise 语法
Promise 是一个构造函数(构造函数可以实例化对象)
Promise接收一个函数作为参数
new Promise(()=>{})
在参数函数里也接收两个参数resolve,reject
new Promise((resolve,reject)=>{})
Promise 实例有两个属性state,result (PromiseStatus,PromiseValue)
let p = new Promise((resolve,reject)=>{})
console.log(p)
Promise的状态有三种
- peding(准备,待解决,进行中)
- fulfilled (已完成,成功)
- rejected(已拒绝 ,失败)
Promise 状态的改变的方法:
通过调用resolve()和reject()改变当前Promise对象的状态,并且状态的改变是一次性的
let p = new Promise((resolve,reject)=>{
resolve()
//reject()//即使调用reject 结果仍然是fulfilled
})
console.log(p)
Promise的结果
let p = new Promise((resolve,reject)=>{
//通过调用resolve,传递参数,改变当前Promise对象的结果
resolve('成功的结果')
// reject('失败的结果')也可以改变结果
})
console.log(p)
Promise 的方法
通过原型_proto_查看到方法:
then():
then 方法是个函数,函数就有参数和返回值,参数有两个。第一个还是一个函数,第二个参数也是函数。
then 的返回值是一个Promise对象
let p = new Promise((resolve,reject)=>{
resolve('成功的结果')
// reject()
})
let t = p.then()
console.log(t) //promise
//then参数
let t = p.then(()=>{},()=>{})
当Promise的状态是fulfilled时,执行then方法里得第一个回调函数,当Promise的状态是rejected时执行第二个回调函数,如果promise的状态不改变。then里的方法不会执行
let p = new Promise((resolve,reject)=>{
resolve('成功的结果')
// reject('失败的结果')
//return 123 //在then方法中通过return 将返回值的promise实例改为fulfilled状态
//console.log(a)如果这里的代码出错会将t实例的状态改成rejected
})
let t = p.then((resolve)=>{
//状态为fulfilled会执行
console.log('成功时候调用')
},()=>{
//状态为rejected执行
console.log('失败时候调用')
})
catch 方法
let p = new Promise((resolve,reject)=>{
//执行catch方法:
// reject()
// console.log(a)
throw new Error('出错了')//主动抛出错误的时候
})
// promise 的状态变为rejected 的时候会执行catch
p.catch((rej)=>{
console.log('错误',rej)
})
console.log(p)
all方法
Promise.all(iterable);
参数:
iterable一个可迭代对象,如 Array 或 String。
Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。
let p1 = new Promise((resolve, reject) => {
resolve('成功了')
})
let p2 = new Promise((resolve, reject) => {
resolve('success')
})
let p3 = Promse.reject('失败')
Promise.all([p1, p2]).then((result) => {
console.log(result) //['成功了', 'success']
}).catch((error) => {
console.log(error)
})
Promise.all([p1,p3,p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 失败了,打出 '失败'
})
race
romse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
},1000)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('failed')
}, 500)
})
Promise.race([p1, p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 打开的是 'failed'
})
经常用的promise书写方式
new Promise((resolve,reject)=>{
}).then(res=>{
}).catch(rej=>{
})
// 链式操作
new Promise((resolve,reject)=>{}).then().then()
promise解决回调地狱
//以前通过id拿name通过name拿邮箱
$.ajax({
type:'GET',
url:'data1.json',
success:function(res){
let {id} = res
$.ajax({
type:'GET',
url:'data2.json',
data:{id},
success:function(res){
let {name} = res
$.ajax({
type:'GET',
url:'data3.json',
data:{name},
success:function(res){
console.log(res.email)
},
error:function(rej){}
})
},
error:function(rej){}
})
},
error:function(rej){}
})
//现在
//封装
function getData(url,data={}){
return new Promise((resolve,reject)=>{
$.ajax({
type:'GET',
url:url,
data:data,
success:function(res){
resolve(res)
},
error:function(rej){
reject(rej)
}
})
})
}
//使用
getData('data1.json').then(res=>{
let { id } = res;
return getData('data2.json',{id})
}).then(res=>{
let { name } = res;
return getData('data3.json',{name})
})
.then(res=>{
console.log(res.email)
})