Promise的基本使用
promise是处理异步操作,避免回调地狱的一个方案
创建Promise
new Promise((resolev, reject) => {
// 这里放异步方法,比如网络请求等,在这里用定时器模拟
console.log('请求数据中');
setTimeout(() => {
let num = parseInt(Math.random() * 10);
if(num > 2 ){
// 成功时会调用resolev方法
let o = {
num,
m: '成功'
}
resolev(o); // 将需要的结果返回
}else{
let m = '失败';
reject(m); // 在失败的时候返回,一旦失败那么整个promise将不会在进行
}
}, 2000)
}).then((res) => {
//当成功时,函数将会进入到这里,res这个参数就是请求数据的结果
console.log(res)
}).catch((err) => {
//失败的结果
console.log(err)
})
首先解释一下这段代码,Promise()传入的是一个函数,可以是箭头函数,也可以是普通函数,然后这个函数的两个参数,依然是函数,resolev
在成功时返回,reject
在失败时返回。
这样一个最简单的promise就创建好了。
链式调用
如果说,有这么一个需求,需要网络请求得到一个数据,再利用这个数据,作为下一个网络请求的参数。
new Promise((resolev, reject) => {
// 这里放异步方法,比如网络请求等,在这里用定时器模拟
console.log('请求数据中');
setTimeout(() => {
let num = parseInt(Math.random() * 10);
if(num > 2 ){
// 成功时会调用resolev方法
let o = {
num,
m: '成功'
}
resolev(o); // 将需要的结果返回
}else{
let m = '失败';
reject(m); // 在失败的时候返回,一旦失败那么整个promise将不会在进行
}
}, 2000)
}).then((res) => {
//当成功时,函数将会进入到这里,res这个参数就是请求数据的结果
// 我在这里成功获取了返回结果,在用这个结果作为参数,给下一个网络请求,这时只要在返回一个promise对象就行了
return new Promise((resolev, reject) => {
setTimeout(() => {
//res.num 上一个请求的结果
let sum = res.num * res.num ;
if(sum < 10000){
resolev(sum)
}else{
reject('失败')
}
}, 1000)
})
}).then((res) => {
// 如果重新返回promise,那么还可以用then去接收,也就是then可以有多个,而catch只会有一个,只要进入到catch也就是失败了,那么整个Promise就不会再进行
console.log(res)
}).catch((err) => {
//失败的结果
console.log(err)
})
Promise.all
还有另一种需求,那就是我有多个网络请求,需要等它们都完成了,才可以进行下一步操作,这时可以用Promise.all()
。
Promise.all
接收一个数组作为参数,数组的元素都是Promise对象实例,只有所有实例都请求成功,Promise.all
才会进入成功的状态,只要有一个是失败的,那么Promise.all
就会进入失败的状态。
let promiseArr = [];
for(let i = 0; i < 3; ++i){
let promise = new Promise((resolev, reject) => {
// 这里放异步方法,比如网络请求等,在这里用定时器模拟
console.log('请求数据中');
setTimeout(() => {
let num = parseInt(Math.random() * 10);
if(num > 2 ){
// 成功时会调用resolev方法
let o = {
num,
m: '成功'
}
resolev(o); // 将需要的结果返回
}else{
let m = '失败';
reject(m); // 在失败的时候返回,一旦失败那么整个promise将不会在进行
}
}, 2000)
})
//将每个Promise实例加入数组中
promiseArr.push(promise);
}
if(promiseArr.length > 0){
Promise.all(promiseArr).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
})
}
Promise.race
Promise.race([p1,p2,p3]);
这个方法也是接收数组,只要里面实例有一个改变状态,那么Promise.race
也会改变状态,而且其他实例不会去处理。
let promiseArr = [];
for(let i = 0; i < 3; ++i){
let promise = new Promise((resolev, reject) => {
// 这里放异步方法,比如网络请求等,在这里用定时器模拟
console.log('请求数据中');
setTimeout(() => {
let num = parseInt(Math.random() * 10);
if(num > 2 ){
// 成功时会调用resolev方法
let o = {
num,
m: '成功'
}
resolev(o); // 将需要的结果返回
}else{
let m = '失败';
reject(m); // 在失败的时候返回,一旦失败那么整个promise将不会在进行
}
}, 2000)
})
//将每个Promise实例加入数组中
promiseArr.push(promise);
}
if(promiseArr.length > 0){
//只要改下方法就行了
Promise.race(promiseArr).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
})
}
看完觉得有帮助的童鞋,请随手一个赞,哪里不对,哪里不懂,请在下方留言,一起谈论,一起进步。