这是我参与更文挑战的第21天,活动详情查看: 更文挑战
但从字面意思上来理解: async是异步的简写,await可以认为是async await的简写,所以可以理解为:async用于声明一个异步的function, 放在声明之前,await用于等待一个异步方法请求完成,然后执行后续代码,通常放在 async 里面。 还有,await只能出现在async函数中。
异步编程的最高境界,就是根本不用关心它是不是异步。
1, async
async 使用在函数前面,把函数变成一个异步函数,返回promise对象
/**
* async 使用在函数前面,把函数变成一个异步函数,返回promise对象
*/
async function hello(str) {
return str;
}
const result = hello("async-1")
console.log(result)
console.log('async-2')
复制代码
输出的结果:
Promise { 'async-1' }
async-2
复制代码
async函数式怎样处理它的返回值,从上面的代码可以看出,async函数返回的是一个promise对象,由此可见:即使在async函数中直接return 一个常量,async也会把这个常量通过Promise.resolve()封装成Promise对象。
Promise.resolve(data) 可以等于 new Promise(resolve => resolve(data))
复制代码
所以:async函数返回的是一个Promise对象,在没有await的情况下,我们之前获取Promise对象的值的方式是通过.then() 这种链式操作来处理
async function hello(str) {
return str;
}
const result = hello("async-1").then((data) => {
console.log(data)
})
console.log('async-2')
复制代码
输出结果:
async-2
async-1
复制代码
2, await
await是等待的意思。await等待的是一个什么东西,当它等待到之后,下一步又要做什么?
一般来说,await是在等待一个async函数完成,因为async函数返回的是一个Promise对象,所以:await是在等待一个async函数的返回值,这个返回值有可能是一个Promise对象,也有可能是一个常量,
问题来了,await 等到了它要等的东西之后,下一步要做什么?
首先:可以理解为:await等待的是一个表达式:
然后:如果await等到的不是一个Promise对象,那么await表达式的运算结果就是它等到的东西。
其次:如果await等到的就是一个Promise对象,await就会阻塞后面的代码,等着Promise对象resolve的结果,等拿到resolve的结果之后,把它作为await表达式的运算结果。
上面的阻塞一词很重要,因为它会阻塞代码,所以它必须要在async函数里面,所有阻塞的代码都必须被封装成一个
Promise对象中才行。
同时:这个阻塞有时也很重要,它可以让异步代码同步执行,在某些需求里面,确实很重要。
复制代码
function one() {
return 'one'
}
async function two() {
return 'two'
}
async function test() {
const t1 = await one()
const t2 = await two()
console.log(t1, t2)
}
test()
复制代码
输出结果:
one two
复制代码
3, async/await
通过上面的第一点和第二点,我们可以明白:async会将其后的函数的返回值封装成一个Promise对象,await会等待这个Promise对象完成,并将其resolve的结果返回出来。
注意: 如果await等到的是一个Promise对象,会主动的将其resolve的结果拿到
如果await等到的不是一个Promise对象,会直接拿到结果
复制代码
下面模拟异步请求操作:通过setTimeout模拟异步操作
方案一:Promise
function testAsync() {
return new Promise((resolve) => {
setTimeout(() => {
resolve('resolve-----ok')
}, 1000)
})
}
testAsync().then(data => {
console.log(data)
})
console.log('我需要等待你吗')
复制代码
输出结果:
我需要等待你吗
resolve-----ok
复制代码
方案二:async/awiat
function testAsync() {
return new Promise((resolve) => {
setTimeout(() => {
resolve('resolve-----ok')
})
})
}
async function test() {
const result = await testAsync()
console.log(result)
}
test()
复制代码
通过上面的方案一和方案二对比,都是异步请求,方案二的优势在于:当有多个.then()链式操作的是欧,await就明显简单很多,其优势也就凸显出来
注意:Promise通过的.then()来解决回调地狱的问题
Async/await 是为了进一步优化Promise的.then()操作,使其更简洁
复制代码
4, promise 结合 async/await
实现异步请求同步执行效果
function one() {
return 'one'
}
function two() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('two')
}, 3000)
})
}
function three() {
return 'three'
}
async function run() {
console.log(one())
console.log(await two())
console.log(three())
}
run()
复制代码
5, 注意点
await 命令后面的 Promise 对象,运行结果可能是 rejected,所以最好把 await 命令放在 try…catch 代码块中
async function test() {
try {
await somethingThatReturnsAPromise();
} catch (err) {
console.log(err);
}
}
复制代码