【问题标题】:Are promise handlers (.then/.catch/.finally) always asynchronous? [closed]承诺处理程序(.then/.catch/.finally)总是异步的吗? [关闭]
【发布时间】:2020-01-29 03:33:59
【问题描述】:

检查这个:https://javascript.info/microtask-queue 第一行说

promise 处理程序 .then/.catch/.finally 始终是异步的

但它们总是按顺序执行。只有当它在中间失败时它才会跳起来捕捉。那它怎么是异步的呢?

【问题讨论】:

  • 他们并不总是这样。 let x = 1; new Promise(r => r(x)).then(console.log); x = 2; 打印 1 但如果它始终是异步的,则会打印 2
  • @Reactgular 所以你的意思是说这是他们的错误?
  • 简答;不,并非总是如此。长答案:由于事件循环的性质,无法保证。您可以在 You Don't Know JS 中阅读更多信息 - 滚动到事件循环部分。
  • @Reactgular 等等。为什么将处理程序的代码与承诺下方的代码进行比较?即使在文章中,他们也给出了类似的例子。但是该语句似乎对处理程序之外的代码没有任何作用
  • 运行let x = 1; new Promise(r => r(x)).then(console.log); x = 2; 具有误导性。您只是在证明 Promise 工厂方法中的代码是同步运行的。但问题是关于 then 延续回调何时运行。运行x = 4; new Promise(r => r(x)).then(() => console.log(x)); x = 5;,你会看到它打印出5,表明延续回调是异步的。

标签: javascript asynchronous async-await es6-promise


【解决方案1】:

promise 的设计 中没有任何内容要求它们的使用是同步的或异步的。这样做的目的是让程序员不必担心代码是两者之一,因此应该假设异步副作用总是会发生。

关于堆栈溢出的最流行(但也很烦人)的问题之一如下:

function fooBar(promise) {
   let y;
   promise.then(value => y = value);
   return y;
}

为什么fooBar() 总是返回undefined

如果使用 Promise 的每个人都假设它们都是异步,那么错误就会减少,并且会更清楚地说明如何使用它们。

异步意味着处理程序不会在同一个 JavaScript 堆栈(事件队列)中执行,因此上述应始终产生 undefined

当使用 同步 承诺时,上述 实际上 工作。这可能会让一些不了解两者之间区别的开发人员感到困惑。这也意味着函数的结果是出乎意料的,因为无法确定承诺的内部性质是同步还是从外部异步

【讨论】:

  • 谢谢。我读过这样的东西。如果我错了,请纠正我。为了处理异步执行,我们可以使用回调。但是回调有一些缺点,因为它可能导致回调地狱或无法理解的代码。因此,promise 是回调的替代方案,它使我们摆脱了这些缺点。这是我目前的理解。但是突然之间我们突然说它是异步的。我知道它以异步方式工作。我认为它是回调的替代品。
  • @logidelic 是的。我是前端新手
  • @AjithKumar 我们有多种选择来处理 JS 中的异步问题。它们包括回调、promise、async/await 和 observables(也称为反应式编程)。学习这些是一段旅程,你应该首先真正掌握回调,然后是 Promise,然后是 async/await,最后是 rxjs。不清楚 Promise 的工作原理会导致 async/await 的使用不佳。因此,请继续阅读并进行实验,看看会发生什么。
  • @Reactgular 好的。谢谢您的帮助。 :)
  • 设计中没有任何内容,但 Promises/A+ 规范确实要求承诺回调异步发生——从不同步。这让开发人员不必担心承诺是“同步”还是“异步”以及您的示例代码将如何发挥作用,这使得事情变得更简单——当使用兼容的实现时,它总是会发挥同样的作用。见规则 2.2.4 promisesaplus.com
猜你喜欢
  • 2019-01-07
  • 2021-10-17
  • 1970-01-01
  • 2016-01-21
  • 1970-01-01
  • 2022-10-25
  • 2016-03-01
  • 2018-12-13
  • 2020-01-11
相关资源
最近更新 更多