一、Promise的介绍和基本使用:
Promise其实是一个构造函数,任何异步操作都可以封装到promise中。
基本使用:
异步函数的普通写法:
setInterval(() => {
console.log('hello promise');
console.log('hello promise');
console.log('hello promise');
console.log('hello promise');
console.log('hello promise');
console.log('hello promise');
setTimeout(() => {
console.log('hello vue');
console.log('hello vue');
console.log('hello vue');
console.log('hello vue');
console.log('hello vue');
console.log('hello vue');
setTimeout(() => {
console.log('hello hels');
console.log('hello hels');
console.log('hello hels');
console.log('hello hels');
console.log('hello hels');
console.log('hello hels');
}, 1000);
}, 1000);
}, 1000);
使用Promise封装:
将原本写在resolve()处的代码封装到then()中,实现请求和处理分离
// 任何异步操作都可以封装到promise中
// 参数 -> 函数(resolve,reject)
// resolve reject本身又是函数
// 链式编程
new Promise((resolve,reject) => {
// 第一次网络请求的代码
setTimeout(() => {
resolve()
}, 1000);
}).then(() => {
// 第一次拿到结果的处理代码
console.log('hello promise');
console.log('hello promise');
console.log('hello promise');
console.log('hello promise');
console.log('hello promise');
console.log('hello promise');
return new Promise((resolve,reject) => {
// 第二次网络请求的代码
setTimeout(() => {
resolve()
}, 1000);
}).then(()=> {
// 第二次拿到结果的处理代码
console.log('hello vue');
console.log('hello vue');
console.log('hello vue');
console.log('hello vue');
console.log('hello vue');
console.log('hello vue');
return new Promise((resolve,reject) => {
// 第三次网络请求的代码
setTimeout(() => {
resolve()
}, 1000);
}).then(()=>{
// 第三次拿到结果的处理代码
console.log('hello hels');
console.log('hello hels');
console.log('hello hels');
console.log('hello hels');
console.log('hello hels');
console.log('hello hels');
})
})
})
什么情况下会用到Promise?
一般情况下使用异步操作时,使用Promise对这个异步操作进行封装
成功时调用resolve
失败时调用reject
new Promise((resolve,reject) => {
setTimeout(() => {
// 成功时调用resolve
// 失败时调用reject
reject('error massage')
}, 1000);
}).then(() => {
console.log(data);
console.log(data);
console.log(data);
}).catch((err) => {
console.log(err);
})
二、Promise的三种状态和另外处理方式:
pending :
等待状态,比如正在进行网络请求,或者定时器没有到时间。
fulfill :
满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调.then()
reject :
拒绝状态,当我们主动回调了reject时,就处于该状态,并且会回调.catch()
另外处理方式:
new Promise((resolve,reject)=>{
setInterval(() => {
resolve('hello promise')
reject('erro massage')
}, 1000);
}).then(data => {
console.log(data)
},err => {
console.log(err)
})
三、Promise的链式调用:
这里我们通过模拟网络请求的方式来写三种调用方法:
模拟网络请求:
网络请求aaa -> 自己处理(10行)
处理:aaa111 ->自己处理(10行)
处理:aaa111222 -> 自己处理
第一种写法:
new Promise((resolve,reject) => {
setTimeout(() => {
resolve('aaa')
}, 1000);
}).then(res => {
// 1.自己处理10行代码
console.log(res,'假装是第一层的10行处理代码');
// 2.对结果进行第一次处理
return new Promise((resolve,reject) => {
resolve(res + '111')
})
// 注意每一个then都是在上一个then之后
}).then(res => {
// 1.自己处理10行代码
console.log(res,'假装是第二层的10行处理代码');
// 2.对结果进行第二次处理
return new Promise((resolve) => {
resolve(res + '222')
})
}).then(res => {
console.log(res,'假装是第三层的10行处理代码');
})
加入reject的写法:
new Promise((resolve,reject) => {
setTimeout(() => {
resolve('aaa')
}, 1000);
}).then(res => {
// 1.自己处理10行代码
console.log(res,'假装是第一层的10行处理代码');
// 2.对结果进行第一次处理
return new Promise((resolve,reject) => {
//resolve(res + '111')
reject('err')
})
// 注意每一个then都是在上一个then之后
}).then(res => {
// 1.自己处理10行代码
console.log(res,'假装是第二层的10行处理代码');
// 2.对结果进行第二次处理
return new Promise((resolve) => {
resolve(res + '222')
})
}).then(res => {
console.log(res,'假装是第三层的10行处理代码');
}).catch(err => {
console.log(err)
})
第二种写法:对第一种的简写:
new Promise(resolve => resolve(结果))简写
Promise.resolve
new Promise((resolve,reject) => {
setTimeout(() => {
resolve('aaa')
}, 1000);
}).then(res => {
// 1.自己处理10行代码
console.log(res,'假装是第一层的10行处理代码');
// 2.对结果进行第一次处理
return Promise.resolve(res + '111')
}).then(res => {
// 1.自己处理10行代码
console.log(res,'假装是第二层的10行处理代码');
// 2.对结果进行第二次处理
return Promise.resolve(res + '222')
}).then(res => {
console.log(res,'假装是第三层的10行处理代码');
})
加入reject:
new Promise((resolve,reject) => {
setTimeout(() => {
resolve('aaa')
}, 1000);
}).then(res => {
// 1.自己处理10行代码
console.log(res,'假装是第一层的10行处理代码');
// 2.对结果进行第一次处理
//return Promise.resolve(res + '111')
return Promise.reject('err massage')
//或者
throw 'err massage'
}).then(res => {
// 1.自己处理10行代码
console.log(res,'假装是第二层的10行处理代码');
// 2.对结果进行第二次处理
return Promise.resolve(res + '222')
}).then(res => {
console.log(res,'假装是第三层的10行处理代码');
}).catch(err => {
console.log(err)
})
第三种写法:对第二种的再简写:
省略掉Promise.resolve
new Promise((resolve,reject) => {
setTimeout(() => {
resolve('aaa')
}, 1000);
}).then(res => {
// 1.自己处理10行代码
console.log(res,'假装是第一层的10行处理代码');
// 2.对结果进行第一次处理
return res + '111'
}).then(res => {
// 1.自己处理10行代码
console.log(res,'假装是第二层的10行处理代码');
// 2.对结果进行第二次处理
return res + '222'
}).then(res => {
console.log(res,'假装是第三层的10行处理代码');
})
四、Promise的all方法:
// 这样写就会等两个请求的数据同时拿到之后放在results数组里再进行下一步操作
Promise.all([
new Promise((resolve,reject) => {
$ajax({
url: 'url1',
success: function (data) {
resolve(data)
}
})
}),
new Promise((resolve,reject) => {
$ajax({
url: 'url2',
success: function (data) {
resolve(data)
}
})
})
]).then(results => {
console.log(results)
})