1. promise
1.1 产生原因
promise帮助我们改造或优化传统的使用回调函数实现的异步操作 解决回调地狱问题
1.2 原理
promise提供了一个构造函数,在使用的时候必须通过new创建一个实例对象,在创建实例对象的时候需要传递一个匿名函数,此时需要
两个参数(resolve,reject)resolve成功处理函数 reject失败处理函数
resolve需要通过promise实例对象提供的.then()
方法来传递,reject 需要通过.catch()
方法来捕获异常
1.3 promise的三个状态
等待中pending、完成resolved、拒绝rejected
1.4 promise的三个实例方法
.then() --得到异步任务正确的结果
.catch() – 获取异常信息
.finally() --成功与否都会执行
- promise必须实现
then
方法,而且then必须返回一个promise,同一个promise的then可以调用多次,并且回调的执行顺序跟它们被定义时的顺序一致,.catch()方法可以捕获任意一个.then()方法的出错
1.5 promise的两个参数
resolve 成功处理函数
reject 失败处理函数
Promise完整例子:
function handel1(){
return new Promise(function(resolve,reject){
var num = Math.ceil(Math.random() * 10); //定义一个1-10的随机数
if(num <= 5){
resolve(num);
}else{
reject('数字超过5了!');
}
})
}
handle1()
.then(data=>{
console.log(data)
console.log('执行了resolve成功回调')
})
.catch(error=>{
console.log(error);
console.log('异常回调catch捕获')
})
// 执行结果有两种
// 2
// 执行了resolve成功回调
// 或者//
// 数字超过5了!
// 异常回调catch捕获
多个promise.then()调用实现
function pro1(){
var p = new Promise(function(resolve,reject){
setTimeout(()=>{
console.log('异步任务1执行完成');
resolve('resolve参数返回1')
// reject('reject参数返回')
},1000)
})
return p;
}
function pro2(){
var p = new Promise(function(resolve,reject){
setTimeout(()=>{
console.log('异步任务2执行完成');
resolve('resolve参数返回2')
// reject('reject参数返回')
},1000)
})
return p;
}
function pro3(){
var p = new Promise(function(resolve,reject){
setTimeout(()=>{
console.log('异步任务3执行完成');
resolve('resolve参数返回3')
// reject('reject参数返回')
},1000)
})
return p;
}
pro1().then(data=>{
console.log('1.then中的data:',data);
return pro2()
})
.then(data=>{
console.log('2.then中的data:',data);
return pro3()
})
.then(data=>{
console.log('3.then中的data:',data);
})
.catch(error=>{
console.log('catch中的error返回:',error);
})
执行结果为:
异步任务1执行完成
1.then中的data: resolve参数返回1
异步任务2执行完成
2.then中的data: resolve参数返回2
异步任务3执行完成
3.then中的data: resolve参数返回3
其中任意一个方法使用reject()将会在catch中捕获打印,并中断后面的.then()方法的执行
1.6 静态方法
all
、allSettled
、race
、any
、reject
、resolve
1.6.1 promise.all()
all() – 在所有异步操作执行完后才执行回调。 返回值是数组
执行所有的方法,方法都执行成功之后才执行.then()方法,以数组形式输出所有函数resolve()中结果;有一个失败都不执行then,如果后面写了catch方法,将会在执行该函数之后进行catch输出
Promise
.all([pro1(),pro2(),pro3()])
.then(results=>{
console.log(results)
})
// 异步任务1执行完成
// 异步任务2执行完成
// 异步任务3执行完成
// ['resolve参数返回1', 'resolve参数返回2', 'resolve参数返回3']
演示 pro2函数返回reject() 模拟执行失败的情况
function pro2(){
var p = new Promise(function(resolve,reject){
setTimeout(()=>{
console.log('异步任务2执行完成');
reject('reject参数返回')
},1000)
})
return p;
}
Promise
.all([pro1(),pro2(),pro3()])
.then(results=>{
console.log(results)
})
.catch(error=>{
console.log(error)
})
// 异步任务1执行完成
// 异步任务2执行完成
// reject参数返回
// 异步任务3执行完成
1.6.2 promise.race()
race() – 只返回一个结果 哪个实例最先执行完 就返回哪个执行结果 【race比赛的意思,看谁快】
将pro3函数的延时改为500毫秒,执行以下代码
Promise
.race([pro1(),pro2(),pro3()])
.then(result=>{
console.log('then执行了',result);
})
// 异步任务3执行完成
// then执行了 resolve参数返回3
// 异步任务1执行完成
// 异步任务2执行完成
以上例子参考地址:大白话讲解promise
1.6.3 Promise.resolve() 和 Promise.reject()
如果涉及到异步操作的时候,需要定义一个new Promise,但有些场景不涉及到异步操作,也想调用.then(),可以使用Promise.resolve()
或Promise.reject()
方法包装成 成功或失败的状态
未使用该方法之前的代码
function fun1(){
return new Promise(function(resolve,reject){
resolve('success')
})
}
fun1().then(result=>{
console.log(result); // 'success'
})
function fun2(){
return new Promise(function(resolve,reject){
reject('error')
})
}
fun2().catch(error=>{
console.log(error); // 'error'
})
使用Promise.resolve()
或Promise.reject()
方法执行
function fun1(){
return Promise.resolve('success2')
}
fun1().then(result=>{
console.log(result); // 'success2'
})
function fun2(){
return Promise.reject('error2')
}
fun2().catch(error=>{
console.log(error); // 'error2'
})
2. async await
出现的原因
async await是基于ES6的Generator 函数和promise的语法糖,async/await 让异步代码看起来、表现起来更像同步代码
,是ES7推出的
概念
async 声明的function是异步函数,await 等待异步方法执行完成。await 只能出现在 async 声明的函数中。
- async用来修饰函数的声明,使用async修饰的函数会变成一个异步函数 await用来修饰函数的调用,被await修饰的函数必须返回一个promise异步对象,会将promise异步对象转换成一个同步操作
async await 简单使用例子:
// promise 的简单使用
function fn1(){
return Promise.resolve('succ')
}
fn1().then(res=>console.log(res)) // 'succ'
// 转换为 async await 的使用
async function fn2(){
var res = await Promise.resolve('succ')
console.log(res)
}
fn2(); // 'succ'
通过上面例子可以看出,await
相当于执行了 .then()
方法,通过赋值给res拿到 fn1() 执行成功返回的值 ‘succ’,直接简化了Promise 异步操作的使用。
- await 在等待一个Promise,或者是其他任意值。如果等待的是Promise ,则返回Promise的处理结果,如果等待其他值,则返回其他值本身。
async function fn1(){
var res = await 'succ'
console.log(res);
}
fn1() // 'succ'
- await 会暂停当前 async function 的执行,等待Promise的处理完成,才会处理await之后的内容。
function testFun(text){
return new Promise(function(resolve,reject){
setTimeout(() => {
resolve(text)
}, 3000);
})
}
async function asyFun(){
var res = await testFun('处理promise')
console.log(res);
console.log('等待上面await执行结果之后执行');
}
asyFun()
// 3s 之后打印
// 处理promise
// 等待上面await执行结果之后执行
- async 处理reject() 返回 ,即 .catch() 的等效处理
trycatch 或 在promise后边直接.catch()处理
// try catch
async function fn4(){
try {
await Promise.reject('error')
} catch (error) {
console.log(error);
}
}
fn4() // 'error'
// promise后面.catch() 处理
async function fn4(){
await Promise.reject('error111').catch(err=>{
console.log(err)
})
}
fn4()
async
和await
可以说是异步终极解决方案了,相比直接使用Promise
来说,优势在于处理then
的调用链,能够更清晰准确的写出代码 ,并且也能优雅地解决回调地狱问题。当然也存在一些缺点,因为await
将异步代码改造成了同步代码,如果多个异步代码没有依赖性却使用了await
会导致性能上的降低。
3.promise async await axios区别
为什么会使用async
async/await 让异步代码看起来、表现起来更像同步代码