Promise 的 .then 和 .catch 是如何工作的?
Posted
技术标签:
【中文标题】Promise 的 .then 和 .catch 是如何工作的?【英文标题】:How does Promise's .then and .catch work under the hood? 【发布时间】:2021-07-28 20:51:50 【问题描述】:我已经知道 Promise 是如何工作的,但我正在尝试更深入地研究以加强我的基础!
所以在阅读了这么多 *** 帖子后,我发现,每个 promise 对象中都有两个主要的数组属性,称为 onFulfillment 和 onRejection,它们是空数组,我们使用 .then 填充 onFulfillment 数组和 .catch 或 .then 的第二个参数填充 onRejection 空数组!
一旦我们的承诺得到落实,这些数组中的函数就会被放入微任务队列中以供稍后执行。
如果我们的 promise 被解决,隐藏的 onFulfillment 数组中的函数将被放入任务队列,但如果我们的 promise 被拒绝,onRejection 数组中的函数将被放入任务队列以供稍后执行,但是,当我测试这个理论时,好像不是这样的!
我确定我的英语不容易理解,所以这里有一些代码,希望能让大家对我在说什么有所了解。
let p = new Promise(function (resolve, reject)
setTimeout(reject, 1000)
)
p.then(x => console.log('done'))
.then(null, x => console.log(true))
p.catch(x => console.log('done'))
我们有一个 .then 和一个 .catch ,我们分别放入 onFulfillment 和 onRejection 数组,1000 毫秒后,放入微任务队列的函数取决于我们的承诺是解决还是拒绝。在我们的例子中,它被拒绝了,所以将 .catch 的函数放到微任务队列中才有意义,然而,似乎 .then 的函数也被放到了任务队列中!
它并没有真正运行,但它被评估为被拒绝的承诺,但如果是这样的话,.then 的函数被放入微任务队列并运行/评估,这意味着它不正确的是,运行什么函数取决于我们的承诺已解决或被拒绝,似乎 .then 和 .catch 都将运行/评估。
【问题讨论】:
here's a bunch of promise implementations - 阅读代码,看看幕后发生了什么 - 我发现“PinkySwear.js”最容易理解 - 整个解决过程也在该网站上进行了深入描述 - @987654322 @ 所有 then() 和 catch() 回调最初都会被捕获,但哪些回调最终会被推送到任务队列中执行,这取决于 Promise 最终是解析还是拒绝。 “所以只有将 .catch 的函数放到微任务队列中才有意义” - 为什么?.then()
最多接受两个函数。第一个将在满足Promise
的情况下执行,第二个将在任何其他情况下执行。第二个.then()
的结果是被拒绝的Promise
,它不是.catch()
ed,因此触发了最后的“catch all”。
【参考方案1】:
我们使用
.then
填充onFulfillment 数组,使用.catch
或.then
的第二个参数填充onRejection 空数组!
不完全是。 then
总是将处理程序放在两个数组中,以便在承诺解决时得到通知。这些处理程序(不是传递的参数!)然后
.then()
已返回的带有调用结果的承诺,
或者,如果没有传递相应状态的回调,则直接将值传播到 .then()
返回的承诺
您可以使用 .then(onFulfilled, onRejected)
、.then(onFulfilled, null)
、.then(null, onRejected)
或 .then(null, null)
- 它们都安装了两个处理程序。
【讨论】:
以上是关于Promise 的 .then 和 .catch 是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章
es6 promise的catch 和 then 的区别认识
Promise 的 .then 和 .catch 是如何工作的?