直接在控制台中编写代码与控制台记录代码有什么区别?

5 javascript console

两者有什么区别:

\n
Promise.all([1,2]) //Promise {<fulfilled>: Array(2)}\n
Run Code Online (Sandbox Code Playgroud)\n

\n
let p1 = Promise.all([1,2]);\nconsole.log(p1) //Promise\xc2\xa0{<pending>}\n
Run Code Online (Sandbox Code Playgroud)\n

为什么控制台显示不同的结果?

\n

T.J*_*der 2

前言:我假设您同时粘贴了第二个示例的两行(let p1 = Promise.all([1,2]);和);console.log(p1)这就是我如何让 Chrome 的控制台执行您所描述的操作。

为什么控制台显示不同的结果?

首先重要的是:这是一个控制台的事情。如何编写自己的代码消耗承诺并不重要。控制台正在做一些您的代码无法做到的“神奇”事情:直接同步访问 Promise 对象的状态。这让它可以构建并显示那些单行快照字符串(Promise {<fulfilled>: Array(2)}Promise{<pending>})。但是您的 JavaScript 代码无法直接访问 Promise 的状态,它只能将履行和拒绝处理程序附加到它,并稍后异步获取该信息。因此,无需担心您所看到的内容存在差异,如果您愿意,现在可以停止阅读。:-)

那么控制台发生了什么?

我们先看一下Promise.all([1, 2])

  • Promise.all循环遍历数组中的每个元素
  • 它将每个元素包裹在一个Promise过孔中Promise.resolve
  • 它将履行和拒绝处理程序附加到这些承诺上
  • 如果任何输入 Promise 拒绝,或者如果所有 Promise 都得到履行,它会拒绝其 Promise,则它会用一组结果(按顺序)履行其 Promise

Promise.all因为只有在代码收到承诺已完成并已解决Promise.all的通知后, Promise才能得到解决,所以 Promise总是以挂起状态开始,从未实现。但由于承诺已完成并已履行,因此他们会尽快发出通知:当当前任务(作业队列中的当前作业)完成时。这意味着一旦您在控制台中键入/粘贴的代码完成运行,而不是在运行时,承诺就会从待处理变为已实现。再加上控制台正在做的“神奇”事情,就解释了这种差异。让我们看看如何:12Promise.all12Promise.all

在第一个示例中,您刚刚放入Promise.all([1, 2])控制台,并让控制台在代码完成后向您显示结果。Promise.all 这意味着控制台会在代码运行完成后看到承诺,显然,在代码Promise.all收到承诺12已履行的通知后。因此,当控制台看到 Promise 对象时,它会发现它已经完成,因此它会显示一个带有Promise {<fulfilled>: Array(2)}.

不过,在第二个示例中,您已将let p1 = Promise.all([1,2]);和粘贴console.log(p1)在一起,因此它们会一起处理。这意味着console.log(p1)运行时,来自的 PromisePromise.all 仍然处于未决状态,因为它还没有机会收到12Promise 已履行的通知。因此控制台显示单行字符串Promise {<pending>}。然后你的代码结束,承诺几乎立即得到履行。

所以这是有趣的行为,但并不重要。在这两种情况下,最初的承诺Promise.all都是悬而未决的,然后会尽快履行。您看到差异的唯一原因是控制台可以“神奇地”直接同步地查看 Promise 的状态,而我们的代码却做不到。