1. 认识promise
1.1 什么是Promise呢
Promise是异步编程的一种解决方案。
什么时候处理异步事件: 常见的场景是网络请求。 封装一个网络请求的函数,因为不能立即拿到结果,所以不能简单的将结果返回。 所以往往会传入另外一个函数,在数据请求成功时,将数据通过传入的函数回调出去。 如果只是一个简单的网络请求,那么这种方案不会带来很大的麻烦。 但是,当网络请求非常复杂时,就会出现回调地狱。
1.2 网络请求的回调地狱
当需要通过一个url1从服务器加载一个数据data1,data1中包含了下一个请求的url2 我们需要通过data1取出url2,从服务器加载数据data2,data2中包含了下一个请求的url3 我们需要通过data2取出url3,从服务器加载数据data3,data3中包含了下一个请求的url4 发送网络请求url4,获取最终的数据data4
2. promise的基本使用
2.1 定时器的异步事件
Promise是ES6引入的异步编程的新解决方案。语法上 Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
//1.使用定时器
setTimeout(() => {
console.log('hello');
},1000)
//2.使用promise 参数->函数(resolve,reject)
//resolve,reject他们本身又是函数
//链式编程
new Promise( (resolve,reject) => {
//第一次网络请求的代码
setTimeout(() => {
resolve()
},1000)
}).then( ()=> {
//第一次拿到结果的处理代码
console.log('hello')
return new Promise((resolve,reject)=>{
//第二次网络请求的代码
setTimeout(()=>{
resolve()
},1000)
})
}).then(()=>{
//第二次拿到结果的处理代码
return new Promise((resolve, reject)=>{
setTimeout(()=>{
console.log('hello')
})
})
})
/*
什么情况下会用到promise
一般情况下是有异步操作时,使用promise对这个异步操作进行封装
new -> 构造函数(1.保存了一些状态 2.执行传入的函数)
在执行传入的回调函数时,会传入两个参数,resolve和reject,其本身又是一个函数
*/
new Promise((resolve, reject) => {
//网络请求
setTimeout(()=>{
//成功的时候调用resolve
//resolve('hello')
//失败的时候调用reject
reject('error message')
},1000)
}).then((data)=>{
//成功的时候用then执行
//网络请求中要处理的代码
console.log(data)
}).catch(err=>{
//失败的时候用catch
console.log(err)
})
2.2 Promise三种状态
pending:等待状态,比如正在进行网络请求,或者定时器没有到时间。
fulfill:满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调.then()
reject:拒绝状态,当我们主动回调了reject时,就处于该状态,并且会回调.catch()
promise的另一种写法
2.4 Promise链式调用
在Promise的流程图中,可以发现无论是then还是catch都可以返回一个Promise对象。 所以,代码其实是可以进行链式调用的: 这里直接通过Promise包装了一下新的数据,将Promise对象返回了
Promise.resovle():将数据包装成Promise对象,并且在内部回调resolve()函数
Promise.reject():将数据包装成Promise对象,并且在内部回调reject()函数
//wrapped into
//网络请求:aaa -> 自己处理一部分(10行)
//处理:aaa111 -> 自己处理(10行)
//处理:aaa111222 -> 自己处理
new Promise((resolve, reject) => {
setTimeout(()=>{
resolve('aaa')
},1000)
}).then(res=>{
//自己处理(10行)
console.log(res,'第一层的10行处理代码')
//2.对结果进行第一次处理
//只使用一个参数时,另一个可以省略
return new Promise(resolve => {
resolve(res + '111')
})
}).then(res=>{
console.log(res,'第二层的10行处理代码')
return new Promise(resolve => {
resolve(res+'222')
})
}).then(res=>{
console.log(res,'第三层的10行处理代码')
})
2.5 链式调用简写
简化版代码:
如果希望数据直接包装成Promise.resolve,那么在then中可以直接返回数据
//new Promise(resolve => resolve(结果)) 简写
new Promise((resolve, reject) => {
setTimeout(()=>{
resolve('aaa')
},1000)
}).then(res=>{
//自己处理(10行)
console.log(res,'第一层的10行处理代码')
//2.对结果进行第一次处理
//只使用一个参数时,另一个可以省略
return Promise.resolve (res + '111')
}).then(res=>{
console.log(res,'第二层的10行处理代码')
return Promise.resolve (res+'222')
}).then(res=>{
console.log(res,'第三层的10行处理代码')
})
//new Promise(resolve => resolve(结果)) 简写
new Promise((resolve, reject) => {
setTimeout(()=>{
resolve('aaa')
},1000)
}).then(res=>{
//自己处理(10行)
console.log(res,'第一层的10行处理代码')
//2.对结果进行第一次处理
//只使用一个参数时,另一个可以省略
// return Promise.resolve (res + '111')
return Promise.reject ('error message')
}).then(res=>{
console.log(res,'第二层的10行处理代码')
return Promise.resolve (res+'222')
}).then(res=>{
console.log(res,'第三层的10行处理代码')
}).catch(err=>{
console.log(err)
})
new Promise((resolve, reject) => {
setTimeout(()=>{
resolve('aaa')
},1000)
}).then(res=>{
//自己处理(10行)
console.log(res,'第一层的10行处理代码')
//2.对结果进行第一次处理
//只使用一个参数时,另一个可以省略
// return (res + '111')
throw 'error message'
}).then(res=>{
console.log(res,'第二层的10行处理代码')
return (res+'222')
}).then(res=>{
console.log(res,'第三层的10行处理代码')
}).catch(err=>{
console.log(err)
})
2.6 all方法的使用
<script>
//请求一
let result1 = false
let result2 = false
$.ajax({
url : '',
success : function () {
console.log('success1')
result1 = true
handler()
}
})
//请求二:
$.ajax({
url : '',
success : function () {
console.log('success2')
result2 = true
handler()
}
})
//需要两个请求都请求到了才继续执行
function handler() {
if(result1 && result2){
//
}
}
//iterator迭代器 all的参数
Promise.all([
new Promise((resolve, reject) => {
$.ajax({
url : '',
success : function (data) {
resolve(data)
}
})
}),
new Promise((resolve, reject) => {
$.ajax({
url : '',
success : function (data) {
resolve(data)
}
})
})
]).then(result => {
//这里的result是一个数组
//result[0] 第一个请求
//result[1] 第二个请求
console.log(result)
})
</script>