async/await的那些事

这是我参与更文挑战的第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);
  }
}
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享