await 到底在等什么?

核心

其实 await 本质上等的是:后面的 thenable 对象的 then 方法调用 resolve 或者 reject

这里面其实包含三个细节:

  1. thenable 对象其实就是包含 then 方法的普通对象。
  2. 如果 await 后面的对象不是一个 thenable 对象,那么系统会将它包装成 thenable 对象。
  3. Promise 对象具有 then 方法,所以 Promise 对象其实也是一个 thenable 对象。

如果理解了这三个细节,那么下面这些测试应该就很好理解了。

测试

测试一:普通 thenable 对象

js 复制代码
const test = async () => {
    try {
        const data = await { then(resolve, reject) { resolve('hello') } }
        console.log(data, 'data')
    } catch (error) {
        console.log(error, 'error')
    }
}
test()
// hello data
js 复制代码
const test = async () => {
    try {
        const data = await { then(resolve, reject) { reject('hello') } }
        console.log(data, 'data')
    } catch (error) {
        console.log(error, 'error')
    }
}
test()
// hello error
js 复制代码
const test = async () => {
    await { then: r => setTimeout(r, 1000) }
    console.log('done')
}

test()
// 1s 之后输出 done

测试二:非 thenable 对象

js 复制代码
const test = async () => {
    const data = await 'hello'
    console.log(data, 'data')
}

test()
// hello data
js 复制代码
const test = async () => {
    const data = await { a: 1 }
    console.log(data, 'data')
}

test()
// { a: 1 } data

测试三:Promise 对象

js 复制代码
const test = async () => {
    try {
        const data = await Promise.resolve('hello')
        console.log(data, 'data')
    } catch (error) {
        console.log(error, 'error')
    }
}
test()
// hello data
js 复制代码
const test = async () => {
    try {
        const data = await Promise.reject('hello')
        console.log(data, 'data')
    } catch (error) {
        console.log(error, 'error')
    }
}
test()
// hello error

总结

总的来说,await 这个操作符,实际上会调用对象的 then 方法,并传入 resolve 和 reject 参数,等我们 then 方法中调用了 resolve 或者 reject 时 await 的结果就等到了。而对于没有 then 方法的对象或者变量,系统会自动生成一个具有 then 方法的对象(也就是Promise对象),然后将该对象或者变量作为 resolve 的参数进行调用返回。

其实我们平时一般会把 await 理解成等到后面 Promise 的返回结果 ,这样理解其实没有什么问题,而且覆盖我们平时编程的绝大多数场景。但是更精细一点的理解其实应该要理解到 await 本质上是在操作对象的 then 方法(调用对象的 then 方法,并传入 resolve、reject,并等待 then 方法去调用他们)。

相关推荐
小小小小宇4 分钟前
前端XSS和CSRF以及CSP
前端
UFIT8 分钟前
NoSQL之redis哨兵
java·前端·算法
超级土豆粉15 分钟前
CSS3 的特性
前端·css·css3
星辰引路-Lefan15 分钟前
深入理解React Hooks的原理与实践
前端·javascript·react.js
wyn2000112827 分钟前
JavaWeb的一些基础技术
前端
江城开朗的豌豆36 分钟前
JavaScript篇:函数间的悄悄话:callee和caller的那些事儿
javascript·面试
Hygge-star41 分钟前
Flask音频处理:构建高效的Web音频应用指南
前端·flask·音视频·pygame·csdn开发云
江城开朗的豌豆1 小时前
JavaScript篇:回调地狱退散!6年老前端教你写出优雅异步代码
前端·javascript·面试
飞鸟malred1 小时前
vite+tailwind封装组件库
前端·react.js·npm
TE-茶叶蛋1 小时前
Vue Fragment vs React Fragment
javascript·vue.js·react.js