Promise.all with $q promise 和 JS 事件循环



假设我在空的AngularJS控制器中有以下代码:

Promise.all([Promise.resolve()]).then(() => console.log('Then'));
setTimeout(() => console.log('setTimeout callback')); 

我期待:

  1. Promise.all.then将被放入事件循环中。
  2. setTimeout回调将被放入事件循环中。

我们不会发出任何长请求,应该有以下输出:
Then
setTimeout callback
它有效。

但是如果我们用$q.resolve()替换Promise.resolve()

Promise.all([$q.resolve()]).then(() => console.log('Then'));
setTimeout(() => console.log('setTimeout callback'));

输出将有所不同:
setTimeout callback
Then

这是一个扑通: https://embed.plnkr.co/0h0i4CzuSgqMbYQtxZtU/
为什么输出不同?$q.resolve如何影响输出?

一些原因:

  • Promise.all不会"检测"已经兑现的承诺,并因此返回立即解决的承诺。它总是使用它们的.then()方法等待其输入承诺(无论如何,它也需要通过此吸收非本机承诺(。由于then回调始终是异步的,因此Promise.all(…)结果始终异步解析(除非可迭代对象为空(,并且稍后安排Promise.all(…).then(…)回调
  • 事件
  • 循环中没有单个事件队列,而是针对不同源的多个事件队列。因此,即使承诺事物在事件循环中需要更多的"滴答声",它们的队列也只是比超时队列更频繁地提供服务。
  • 我们不知道$q正在使用什么机制来使其承诺回调异步。我们只知道它不是原生承诺的,因此使用不同的、显然"更慢"的队列。

通常,您不能(不应该(依赖异步回调以任何特定顺序调用,除非他们的文档提到了它。在需要时明确排序(例如使用承诺(。

最新更新