千家信息网

v8是如何实现更快的await

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,本篇内容介绍了"v8是如何实现更快的await "的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Exa
千家信息网最后更新 2026年10月31日v8是如何实现更快的await

本篇内容介绍了"v8是如何实现更快的await "的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

Example

首先看下代码:

const p = Promise.resolve();

(async () => {

await p;

console.log("after:await");

})();

p.then(() => {

console.log("tick:a");

}).then(() => {

console.log("tick:b");

});

以 node v10 的执行结果为准,node v8 的实现是不符合ECMAScript 标准

优秀的程序员总是能以简单的例子解释复杂的原理。代码很简单,但是执行结果可能出乎很多人意料:

tick:a

tick:b

after:await

如果你已经猜对了,本文的关键内容你已经掌握,不用往下看了:)。

为什么 after:await会出现在tick:a之后,甚至是tick:b之后? 要理解其中的原理,我们可以做一个小实验。

将 await 翻译成 promise

v8博客中是以伪代码的方式解释await的执行逻辑:

原图 https://v8.dev/_img/fast-async/await-under-the-hood.svg

我们可以用promise语法写成:

function foo2(v) {

const implicit_promise = new Promise(resolve => {

const promise = new Promise(res => res(v));

promise.then(w => resolve(w));

});

return implicit_promise;

}

按照同样的方式,可以将文章开头的代码转换成:

const p = Promise.resolve();

(() => {

const implicit_promise = new Promise(resolve => {

const promise = new Promise(res => res(p));

promise.then(() => {

console.log("after:await");

resolve();

});

});

return implicit_promise;

})();

p.then(() => {

console.log("tick:a");

}).then(() => {

console.log("tick:b");

});

经过一些琐碎的调试,发现问题真正的关键代码是这一句: const promise = new Promise(res => res(p));

Resolved with another promise

了解 Node.js 或浏览器的事件循环的童鞋都知道,resolved promise 的回调函数(reaction)是放在一个单独的队列MicroTask Queue中。 这个队列会在事件循环的阶段结束的时候被执行,只有当这个队列被清空后,才能进入事件循环的下一个阶段。

我们知道一个 promise 的 .then 回调的返回值可以是一个任意值,也可以是另外一个 promise。 但是后者的处理逻辑可能有点反直觉。

在深入之前,我们简单说一下 promise 的几种状态:

我们说一个 promise 是 resolved 的,表示它不能被再次 fulfill 或 reject, 要么是被 fulfill,要么被 reject(这两种情况,promise 均有一个确定的 non-promise result), 要么遵循另外一个 promise(随之 fulfill 或 reject)

我们说一个 promise 是 unresolved 的,表示它尚未被 resolve

当一个 promise(假设叫 promiseA。方便引用) 被 resolve,并且去遵循另外一个 promise(叫 p) 时,执行逻辑和前面两种 resolve 情况非常不同,用伪代码表示则是:

addToMicroTaskQueue(() => { // 任务A

// 使用 .then 方法,将 promiseA 的状态 和 p 绑定

p.then(

resolvePromiseA, // 任务B

rejectPromiseA

);

});

我们一步一步来分析:

首先,我们在MicroTask Queue添加任务A,该任务在 ECMAScript 标准 中被定义为 PromiseResolveThenableJob

任务A,主要目的是使 promiseA 遵循 p 的状态,将两者的状态关联起来。

由于我们例子中 p 已经是 resolved(状态为fulfilled)的,所以立即将resolvePromiseA任务B 添加到MicroTask Queue中

在 resolvePromiseA 执行后,promiseA 才是 resolved (状态为 fulfilled,值为 p 的 fulfilled value)

我们可以看到,从 new Promise(res=>res(p)) 到该调用返回的 promise 真正被 resolve 至少需要两次microtick——在我们的例子中,是遍历了两次 MicroTask Queue

这个时候,我们终于可以理清楚开头代码的执行顺序:

01月28日更新,之前微任务队列里面的任务没有考虑顺序,这里做一下修改,以下队列里的任务是顺序有关,从左往右,左边的先执行

1、当代码执行完后

MicroTask Queue有两个任务:PromiseResolveThenableJob,tick:a

2、开始执行 runMicrotasks()

MicroTask Queue变成:resolvePromiseA,tick:b

console: tick:a

3、MicroTask Queue没有清空,继续执行队列中的任务

MicroTask Queue变成:after:await

console: tick:a, tick:b

4、继续执行,清空MicroTaak Queue

console: tick:a, tick:b, after:await

"v8是如何实现更快的await "的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

任务 代码 状态 队列 事件 例子 内容 情况 要么 逻辑 顺序 循环 更快 关键 原理 开头 文章 方式 时候 更多 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州为想互联网科技有限公司 山东特亿宝互联网科技有限公司 科技赋能下的互联网金融 互联网科技集团 苏州互联网科技贷款公司 沃里互联网科技 互联网科技公司有哪些 科技与互联网的利与弊 互联网科技产品 注册互联网科技公司经营范围大全 燊美集互联网科技有限公司 乌鲁木齐新华智原互联网科技学校 中国互联网公司排名锤子科技 信承诺互联网科技有限公司 萌小萌互联网科技河南有限公司 互联网公司属于科技吗 西安左小互联网科技有限公司 玉溪新华互联网科技怎么选 互联网领先科技成果宣传视频 银川新华互联网科技学校招聘 互联网金融科技 互联网科技公司简介 江苏根荣互联网科技 互联网科技行业发展 互联网科技logo 黑科技闪耀互联网之光 中国互联网十大科技股排名 乌苏新华互联网科技做什么的 本届互联网博览会上的黑科技 合肥互联网科技公司公章图片
0