一、Promise
1.1 简单介绍
- ES6中一个非常重要和好用的特性就是Promise
- Promise是异步变成的一种解决方案
- 我们什么时候回处理异步事件呢?
- 一种很常见的应用场景就是网络请求
- 我们封装一个网络请求的函数,因为不能立即拿到结果,所有不能直接显示结果返回
- 所以往往我们会传入另外一个函数,在函数请求成功时,将数据通过传入的函数回调出去
- 如果只是一个简单的网络请求,name这种方案不会给我们带来很大的麻烦
- 但是,当网络请求非常复杂时,就会出现回调地狱
1.2 定时器的异步时间
我们先来看Promise的基本语法
- 这里,我们用哪个一个定时器来模拟异步时间
- 假设下面的data是从网络上一秒后请求的数据
- console.log 就是我们处理的方法
- 这事我们过去的处理方法
setTimeout(function(){
let data = 'hello'
console.log(content);
},1000)
- 换成Promise 代码
// 参数 --> 函数 (resolve,reject)
new Promise((resolve,reject) => {
setTimeout(function(){
resolve('hello')
reject('Error Data')
},1000)
}).then(data => {console.log(data);
}).catch(error => {
console.log(error)
})
// 什么情况下使用promise :
// 1. 一般情况下使用Promise 对这个异步操作进行封装
首先你会觉得多此一举
- 上面的Promise代码明显看起来要复杂
- 其次,Promise代码中的resolve,reject,then,catch 都是些什么东西?
- resolve:捕获网络请求成功后的结果交给then执行
- reject: 捕获网络请求失败后的error信息交给catch执行
1.3 Promise 三种状态
- pending : 等待状态,比如正在进行网络请求,或者定时器没到时间
- fulfill:满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调.then()
- reject: 决绝状态,当我们主动回调reject时,就处于该状态,并且会回调.catch()
1.4 Promise 的另外一个写法
new Promise((resolve,reject) => {
setTimeout(() => {
resolve('hello ok')
reject('error no')
},1000)
}).then(data => {
console.log(data)
},err =>{
console.log(err)
})
1.5 Promise 链式调用
-
我们在看Promise的流程图时,发现无论是then 还是catch都可以返回一个Promise对象,所以我们的代码其实是可以进行链式调用的:
-
这里我们直接通过Promise 包装一下新的数据,将Promise 对象返回
- Promise.resolve(): 将数据包装成Promise对象,并且在内部回调resolve()函数
- Promisereject(): 将数据包装成Promise对象,并且在内部回调reject() 函数
// 链式调用的代码
new Promise((resolve,reject) => {
setTimeout(function(){
resolve('qzk')
},1000)
}).then(data => {
console.log(data); // qzk
// 方法一:原生方法
//return new Promise((resolve,) =>{
// resolve( data+'111')
//})
// 方法二:
//return Promise.resolve(data + '111')
// 方法三:省略掉 Promise.resolve()
return data + '1111'
}).then(data => {
console.log(data); // qzk111
return Promise.reject(data + 'error')
// 或者可以手动抛出异常,给catch捕获
// throw 'error'
}).then(data => {
console.log(data) // 这里不打印
return Promise.resolve(data + '333')
}).catch(error => {
console.log(error) // qzk111error
})
1.6 Promise 的all 方法
需求:一个渲染或其他事件依赖于两个请求(请求1,请求二)
Promise.all([
new Promise((resolve,reject) => {
// 伪代码 ajax 发送请求一
$ajax({
url:'http://127.0.0.1:8000/ajax1/'
success:function(data){
resolve(data)
}
})
}),
// 伪代码 ajax 发送请求二
$ajax({
url:'http://127.0.0.1:8000/ajax2/'
success:function(data){
resolve()
}
})
]).then(results => {
// 第一个网络请求的结果
console.log(results[0])
// 第二个网络请求的结果
console.log(results[1])
})