一看就懂的 promise、 async 和await

Promise

用法

new Promise((resolve , reject) => {
	//...此处执行你的代码
	// resolve("成功") -> 执行成功回调
	// reject("失败") -> 执行失败回调
}).then(res => {
	console.log(res) //输出: 成功
}).catch(err => {
	console.log(err) //输出: 失败
})
// 不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。
.finally(() => {
	console.log('finally');
});

在这里 先了解一下promise的三种状态

  • pending: 初始值
  • fulfilled: 代表操作成功
  • rejected: 代表操作失败

业务场景: 想要实现异步操作,比如你需要获取一个接口的参数后,才执行后面的操作

附上例子

function getData () {
	return new Promise((resolve , reject) => {
		// ...这里调用获取数据接口
		//假设获取的数据是data
		let data = '数据'
		resolve(data)
	})
}

getData().then(res => {
	console.log(res) //这里拿到上面接口数据
	// ...执行拿到数据后的操作
})

async、await

async

在函数前面加上async关键字,表示这是一个异步函数

async function doit() {
	return 'to doit'
}
doit() //为了判断他不会阻塞后面的代码执行,在他后面输出一句话
console.log('我在后面,但是我会先执行')

控制台输出
在这里插入图片描述
这里看出他确实不会阻塞后面的代码执行,但是调用了doit函数,没有输出,打印一下这个函数,看看会输出什么。

async function doit() {
	return 'to doit'
}	
console.log(doit())
console.log('我在后面,但是我会先执行')

控制台输出
在这里插入图片描述
这里控制台打印的是一个promise对象,说明async返回的是一个promise对象,那么我们现在再来写个then方法来获取promise的返回值

async function doit() {
	return 'to doit'
}	
doit().then(res => {
	console.log(res)
})
console.log('我在后面,但是我会先执行')

控制台输出
在这里插入图片描述
我们获取到了doit函数的返回值,而且和上面说的一致,也没有阻塞后面代码的执行。
注意刚刚控制台打印出的promise对象的状态是fulfilled, 回想一下文章开头介绍的promise三种状态,我们这里修改一下函数,让他能处理promise对象返回的成功失败状态
在这里插入图片描述

async function doit(flag) {
	if (flag) {
		return 'to doit'
	} else {
		throw 'not to doit'
	}
}
doit(false).then(res => {
	console.log(res)
}).catch(err => {
	console.log(err)
})
doit(true).then(res => {
	console.log(res)
}).catch(err => {
	console.log(err)
})

控制台输出
在这里插入图片描述
运行过程: 第一次调用doit函数时,传入的flag为false,返回一个决议为失败的promise对象,执行失败的回调;
第二次调用doit函数时,传入flag为true,返回一个决议为成功的promise对象,执行成功回调。

await

学会了async关键字的用法,再来看看await关键字。
await关键字只能放async函数里面,他后面可以放任何表达式,一般我们会放一个返回promise对象的表达式。

// 2s后返回一个双倍的值
function doubleResult(num) {
	return new Promise((resolve , reject) => {
		setTimeout(() => {
			resolve(num*2)
		},2000)
	})
}
// 写一个async函数,可以用到这里的await关键字
async function getDoubleResult() {
	let result = await doubleResult(5)
	console.log(result)
}
getDoubleResult() //2s后获得了数字10

这里getDoubleResult异步函数遇到await关键字,代码就暂停执行了,等待await右边的表达式执行完毕,promise决议为resolve了,拿到返回值,然后代码暂停结束,开始继续执行。

但是,这样呢还不能明显的看出async await的作用

// 加定时器的作用是为了更直观的看出异步执行
function fn1 (num) {
	return new Promise ((resolve , reject) => {
		setTimeout(() => {
			resolve(num*2)
		},3000)
	})
}
function fn2 (num) {
	return new Promise ((resolve , reject) => {
		setTimeout(() => {
			resolve(num*2)
		},2000)
	})
}
function fn3 (num) {
	return new Promise ((resolve , reject) => {
		resolve(num*2)
	})
}
	
async function test() {
	let num1 = await fn1(5)
	let num2 = await fn2(10)
	let num3 = await fn3(20)
	console.log(num1+num2+num3) // 5s后控制台打印出 70
}
test()

这里我们可以看到代码按照我们写的顺序依次执行的,就像在写同步代码一样,再也没有回调地域了
特别注意:如果promise没有一个成功的值传入,对await来说就算是失败了,下面的代码就不会执行

所以不管await后面的代码是同步还是异步,await总是需要时间,从右向左执行,先执行右侧的代码,执行完后,发现有await关键字,于是让出线程,阻塞代码

最后说一个小知识点,Promise本身是同步的,他的回调then和catch是异步的
关于同步和异步的问题,下一篇文章再来详细探讨~~

参考:https://www.cnblogs.com/yuanyingke/p/10280681.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值