promise 和 async await

本文详细解释了Promise的工作原理、状态和方法,以及async/await的出现原因、概念和使用,强调了它们如何优化异步代码和避免回调地狱。同时讨论了asyncawait与axios的区别,指出其优缺点和适用场景。
摘要由CSDN通过智能技术生成

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 静态方法

allallSettledraceanyrejectresolve

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 声明的函数中。

  1. 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 异步操作的使用。

  1. await 在等待一个Promise,或者是其他任意值。如果等待的是Promise ,则返回Promise的处理结果,如果等待其他值,则返回其他值本身。
async function fn1(){
    var res = await 'succ'
    console.log(res);
}
fn1() // 'succ'
  1. 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执行结果之后执行
  1. 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()

asyncawait可以说是异步终极解决方案了,相比直接使用Promise来说,优势在于处理then的调用链,能够更清晰准确的写出代码 ,并且也能优雅地解决回调地狱问题。当然也存在一些缺点,因为await将异步代码改造成了同步代码,如果多个异步代码没有依赖性却使用了await会导致性能上的降低。

参考地址–深入使用async await

3.promise async await axios区别

为什么会使用async
async/await 让异步代码看起来、表现起来更像同步代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值