1.异步请求
当我们在进行数据请求的时候一般会开启异步的任务,因为当我们在执行一段js代码的时候,如果不是异步,请求数据之后的代码就不会再执行,会影响到和用户的交互,比如说后面有一段点击按钮的代码,之后用户点击就没有效果。当请求完数据之后我们会执行一段回调函数,从回调函数之后拿到请求来的数据,之后再操作数据。
2.回调地狱:
当回调函数1里面取到的data1中,包含下一个请求url2,我们就需要从data1中取出url2,从服务器加载出来data2,data2中又包含下一个请求url3,…,这样的代码会很繁琐,不易维护,
promise就是用来解决这类问题。
3.promise
---------------3.1 什么情况下会使用promise呢?
一般情况下是有异步操作的时候,使用promise对这个异步操作进行封装,
<script>
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('guodong')
},1000)
}).then((data)=>{
console.log('hello'+ data)
})
</script>
这里的Promise有两个参数resolve和reject,resolve和reject本身又是函数
这里用promise的好处是:可以把数据请求和数据处理分开操作,使得代码更加的清楚,中间是通过resolve(data),把要处理的数据传到then中,也就是说resolve(data) 中的data最后当做then的参数
<script>
new Promise((resolve,reject)=>{
setTimeout(()=>{
// 成功的时候是调用resolve
// resolve('guodong')
reject('error message')
},1000)
}).then((data)=>{
console.log('hello'+ data)
}).catch((error)=>{
console.log(error)
})
</script>
这里可以看到当数据请求成功的时候,是使用resolve,失败的时候是使用reject
-----------------promise的三种状态
1)pending:等待状态
2)fulfill :满足状态,当主动调用resolve时,就会处于该状态,并且会回调 .then()
3) reject:拒绝状态,调用reject时,就处于该状态,并且会回调 .catch()
<script>
new Promise((resolve,reject)=>{
setTimeout(() => {
// resolve('guodong')
reject('error message')
}, 1000);
}).then(data=>{
console.log(data)
},err=>{
console.log(err)
})
</script>
另外一种方式:是在then里面放置两个函数,逗号分割开
--------------promise的链式调用以及简写方式:
方式一:
new Promise((resolve,reject)=>{
setTimeout(() => {
resolve('aaa')
}, 1000);
}).then((data)=>{
console.log(data)
return new Promise ((resolve)=>{
resolve(data +'111')
})
}).then((data)=>{
console.log(data)
return new Promise((resolve)=>{
resolve(data +'222')
})
}).then((data)=>{
console.log(data)
})
其中在then里面新new的promise里面并没有对异步进行封装,它的目的是拿到resolve,并对数据进行处理,为此开发者进行了简化
new Promise((resolve,reject)=>{
setTimeout(() => {
resolve('aaa')
}, 1000);
}).then((data)=>{
console.log(data)
return Promise.resolve(data+'111')
}).then((data)=>{
console.log(data)
return Promise.resolve(data+'222')
}).then((data)=>{
console.log(data)
})
即直接promise.resolve(),更简便的是可以直接return
new Promise((resolve,reject)=>{
setTimeout(() => {
resolve('aaa')
}, 1000);
}).then((data)=>{
console.log(data)
return data +'111'
}).then((data)=>{
console.log(data)
return data +'222'
}).then((data)=>{
console.log(data)
如果是reject,同样可以调用Promise.reject(‘error message’)
另一种相对于resolve中return方式的是,可以直接throw抛出错误信息
new Promise((resolve,reject)=>{
setTimeout(() => {
resolve('aaa')
}, 1000);
}).then((data)=>{
console.log(data)
throw 'My fault'
}).catch((err)=>{
console.log(err)
})
aaa
My fault
---------------------Promise中的all方法
对于要同时的处理两个请求,对两个请求的结果一起进行处理,此时需要使用到all方法
Promise.all([
new Promise((resolve,reject)=>{
setTimeout(() => {
resolve('guodong')
}, 1000);
}),
new Promise((resolve,reject)=>{
setTimeout(() => {
resolve('gd')
}, 1000);
})
]).then((result)=>{
console.log(result[0])
console.log(result[1])
})
此时拿到的result是一个数组,result[0]表示的是第一个请求的结果,result[1]表示的是第二个请求的结果