假设我在空的AngularJS控制器中有以下代码:
Promise.all([Promise.resolve()]).then(() => console.log('Then'));
setTimeout(() => console.log('setTimeout callback'));
我期待:
Promise.all.then
将被放入事件循环中。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
正在使用什么机制来使其承诺回调异步。我们只知道它不是原生承诺的,因此使用不同的、显然"更慢"的队列。
通常,您不能(不应该(依赖异步回调以任何特定顺序调用,除非他们的文档提到了它。在需要时明确排序(例如使用承诺(。