两者有什么区别:
\nPromise.all([1,2]) //Promise {<fulfilled>: Array(2)}\nRun Code Online (Sandbox Code Playgroud)\n和
\nlet p1 = Promise.all([1,2]);\nconsole.log(p1) //Promise\xc2\xa0{<pending>}\nRun Code Online (Sandbox Code Playgroud)\n为什么控制台显示不同的结果?
\n前言:我假设您同时粘贴了第二个示例的两行(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.resolvePromise.all因为只有在代码收到承诺已完成并已解决Promise.all的通知后, Promise才能得到解决,所以 Promise总是以挂起状态开始,从未实现。但由于承诺已完成并已履行,因此他们会尽快发出通知:当当前任务(作业队列中的当前作业)完成时。这意味着一旦您在控制台中键入/粘贴的代码完成运行,而不是在运行时,承诺就会从待处理变为已实现。再加上控制台正在做的“神奇”事情,就解释了这种差异。让我们看看如何:12Promise.all12Promise.all
在第一个示例中,您刚刚放入Promise.all([1, 2])控制台,并让控制台在代码完成后向您显示结果。Promise.all 这意味着控制台会在代码运行完成后看到承诺,显然,在代码Promise.all收到承诺1并2已履行的通知后。因此,当控制台看到 Promise 对象时,它会发现它已经完成,因此它会显示一个带有Promise {<fulfilled>: Array(2)}.
不过,在第二个示例中,您已将let p1 = Promise.all([1,2]);和粘贴console.log(p1)在一起,因此它们会一起处理。这意味着console.log(p1)运行时,来自的 PromisePromise.all 仍然处于未决状态,因为它还没有机会收到1和2Promise 已履行的通知。因此控制台显示单行字符串Promise {<pending>}。然后你的代码结束,承诺几乎立即得到履行。
所以这是有趣的行为,但并不重要。在这两种情况下,最初的承诺Promise.all都是悬而未决的,然后会尽快履行。您看到差异的唯一原因是控制台可以“神奇地”直接同步地查看 Promise 的状态,而我们的代码却做不到。