乐趣区

关于javascript:如果await-同一个-Promise-两次会怎么样

先看上面这道面试题:

let counter = 0;
const increment = new Promise(resolve => {
  counter++;
  resolve();});
await increment;
await increment;
console.log(counter); // 后果是什么?

你认为 counter 的值是什么?

什么是 promise?这是否意味着“稍后再做”?

实际上应该把 promise 看成是一个状态机。

promise 以“pending”状态开始它的生命周期。如果你要在这个状态下查问后果,则必须排队。

依据 ECMAScript 规范文档中的形容(https://tc39.es/ecma262/),下面 Promise 构造函数会立刻调用咱们的执行器函数。它的 counter++ 副作用运行。不带任何参数调用 resolve(),在 promise 上存储一个 undefined 后果,并将其状态晋升为“fulfilled”。

第一个 await 运行。await 等同于在你的 promise 上运行 .then(onFulfilled),将 onFulfilled 设置为“后面的代码”。这项工作作为微工作进入队列。JavaScript 以先进先出的程序执行微工作;管制最终返回给咱们的函数。

第二个 await 没有什么不一样的中央。它创立一个微工作给我 promise 的后果并提前运行代码,而后期待 JavaScript 进行调度。

副作用只在 Promise 构建期间运行过一次,所以 counter1.

咱们推延了工作吗?没有。promise 是同步创立和执行的。然而咱们应用了 await 来解决其余微工作。

那么应该怎么推延工作?

const microtask = Promise.resolve()
.then(() => console.log('hello from the microtask queue'));

const macrotask = new Promise(resolve =>
  // 排队宏工作
  setTimeout(() => {console.log('hello from the macrotask queue');
    resolve();})
  // 没有解决,promise 仍处于 pending 状态
);

// 这是最先输入的;咱们胜利地推延了工作
console.log('hello from the original execution context');

// yield 调度器; 运行 .then() 并输入日志
await microtask;
// yield 调度器;  promise 的状态是 fulfilled,所以没有日志输入
await microtask;

// yield 调度器; 执行所有微工作,而后运行宏工作并输入日志
await macrotask;
// yield 调度器; promise 曾经实现,所以没有日志输入
await macrotask;

Promise 构造函数是同步运行的,然而咱们不用同步调用 resolve()Promise.prototype.then 也推延了工作。

Promise 构造函数和 Promise.prototype.then 都不会反复工作。

这意味着 promise 能够用来记住异步计算。如果你用了一个 promise,而且想要稍后再次用到它的后果,应该思考保留 promise 而不是它的后果。


本文首发微信公众号:前端先锋

欢送扫描二维码关注公众号,每天都给你推送陈腐的前端技术文章


欢送持续浏览本专栏其它高赞文章:

  • 深刻了解 Shadow DOM v1
  • 一步步教你用 WebVR 实现虚拟现实游戏
  • 13 个帮你进步开发效率的古代 CSS 框架
  • 疾速上手 BootstrapVue
  • JavaScript 引擎是如何工作的?从调用栈到 Promise 你须要晓得的所有
  • WebSocket 实战:在 Node 和 React 之间进行实时通信
  • 对于 Git 的 20 个面试题
  • 深刻解析 Node.js 的 console.log
  • Node.js 到底是什么?
  • 30 分钟用 Node.js 构建一个 API 服务器
  • Javascript 的对象拷贝
  • 程序员 30 岁前月薪达不到 30K,该何去何从
  • 14 个最好的 JavaScript 数据可视化库
  • 8 个给前端的顶级 VS Code 扩大插件
  • Node.js 多线程齐全指南
  • 把 HTML 转成 PDF 的 4 个计划及实现

  • 更多文章 …
退出移动版