1.异步请求
在学习promise的时候我们先看一个异步请求
javascript
function requestData(name) {
setTimeout(() => {
if (name === 'test') {
return 111;
} else {
return 222;
}
}, 1000);
}
console.log(requestData('test'));//undefined
因为setTimeout 函数是异步的,这意味着它不会立即返回结果。而是在1s后执行。在调用requestData方法时,实际打印的是requestData函数的返回值,由于此函数并没有return语句,所以返回是undefined。如果要拿到异步请求的返回值,我们要使用回调函数,使用回调函数能够拿到异步请求的返回值,是因为回调函数被设计为在异步操作完成时被调用,并将异步操作的结果作为参数。
scss
function requestData(name, success, failed) {
setTimeout(() => {
if (name === 'test') {
success(111);
} else {
failed(222);
}
}, 1000);
}
requestData(
'test',
(res) => console.log(res),
(err) => console.log(err)
)
//111
可以看到通过回调函数我们可以拿到异步函数的请求结果。但是我们需要自己去设计回调函数,而且不同的人,他设计的函数各有不同,我们还需要去了解这个函数的设计模式。因此有了promise去统一这种请求方式,另外promise还可以避免回调地狱的产生,使用then,catch方法,增大了代码的可读性。
在通过new创建Promise对象时,我们需要传入一个回调函数,我们称之为executor,这个回调函数会被立即执行,并且给传入另外两个回调函数resolve、reject,当我们调用resolve回调函数时,会执行Promise对象的then方法传入的回调函数;
2.Promise代码结构
javascript
const promise = new Promise((resolve, reject) => {
resolve('哈哈');
reject('错误信息');
});
promise
.then((res) => {
console.log('res', res);
})
.catch((err) => {
consloe.log('err', err);
});
//res,哈哈
在这里通过executor我们调用了resolve和reject方法,但是终端打印的结果只有一个res的,即在Promise中只调用了resolve函数,这个是何Promise里面的状态有关,Promise里面有三种状态(Pending,Fulfilled,Rejected)。在上面的代码在new Promise里就是pending状态,由于先调用了resolve方法,此时状态就会变成Fulfilled。而下面的reject方法,由于此时状态不再是pending状态,将不再执行reject方法。
3.Promise的对象方法
1) then方法
then方法本身也是有返回值的, 它的返回值是Promise。如果我们返回的是一个普通值(数值/字符串/普通对象/undefined), 那么这个普通的值被作为一个新的Promise的resolve值
javascript
promise.then(res => {
return "aaaaaa"
}).then(res => {
console.log("res:", res)
return "bbbbbb"
})
//res: aaaaaa
如果我们返回的是一个Promise
javascript
promise
.then((res) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(111111);
}, 3000);
});
})
.then((res) => {
console.log('res:', res);
});
//res: 11111
2)catch方法
javascript
const promise = new Promise((resolve, reject) => {
reject('111111');
});
promise
.then((res) => {
console.log('res:', res);
})
.catch((err) => {
console.log('err:', err);
return 'catch return value';
})
.then((res) => {
console.log('res result:', res);
})
.catch((err) => {
console.log('err result:', err);
});
// err: 111111
// res result: catch return value
当调用了reject方法时会去调用catch方法,调用了catch方法后,因为返回了的是一个新的Promise对象,所以他的执行一个新的resolve,除非在调用的时候继续promise的reject,或者抛出异常,它才会调用catch方法。
- finally方法
javascript
const promise = new Promise((resolve, reject) => {
// resolve("resolve message")
reject("reject message")
})
promise.then(res => {
console.log("res:", res)
}).catch(err => {
console.log("err:", err)
}).finally(() => {
console.log("finally code execute")
})
//err: reject message
//finally code execute
这个finally方法是最终的意思,最后都会调用一下。
4.Promise类方法
1)all与allSettled
javascript
// 创建多个Promise
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(11111)
}, 1000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(22222)
}, 2000);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(33333)
}, 3000);
})
// all
//Promise.all([p2, p1, p3, "aaaa"]).then(res => {
// console.log(res)
//}).catch(err => {
// console.log("err:", err)
//})
// err: 22222
// allSettled
Promise.allSettled([p1, p2, p3])
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
[
{ status: 'fulfilled', value: 11111 },
{ status: 'rejected', reason: 22222 },
{ status: 'fulfilled', value: 33333 }
]
要所有的Promise都变成fulfilled时, 再拿到结果。在拿到所有结果之前, 有一个promise变成了rejected, 那么整个promise是rejected。allSettled会打印所有状态与结果
2)race与any
javascript
// 创建多个Promise
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(11111)
}, 3000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(22222)
}, 500);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(33333)
}, 1000);
})
// race: 竞技/竞赛
// Promise.race([p1, p2, p3]).then(res => {
// console.log("res:", res)
// }).catch(err => {
// console.log("err:", err)
// })
//err: 22222
// any方法
Promise.any([p1, p2, p3]).then(res => {
console.log("res:", res)
}).catch(err => {
console.log("err:", err.errors)
})
res: 33333
race它会选择最先完成(无论成功还是失败)的那个Promise。any是根据状态执行的,只要一组中其中一个的状态变为fulfilled,那么Promise.any的状态就会变成fulfilled。