- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
$q service AngularJS 中非常强大,通过异步代码让我们的生活更轻松。
我是 Angular 新手,但使用延迟 API 对我来说并不是很新鲜。我必须说我完全同意文档的如何使用
部分+文档中有非常有用的链接+我也检查了源代码。
我的问题更多是关于 Angular 中延迟和 promise API 对象的底层部分。它们的生命周期的具体阶段是什么,以及它们如何与rootScope.Scope
交互。我的假设是,当 promise 解决时 - 它会调用摘要循环???是/否?
能否针对以下几个方面提供具体的详细答案:
我将欣赏并接受最详细的答案,并尽可能多地引用文档或来源(我自己找不到)。我找不到任何以前与此主题相关的讨论(如果已有讨论),请发布链接。
ps:如果有人为该问题提供更好的标题,请+1,请在评论中添加您的建议。
干杯!
最佳答案
Promise 具有三种状态
.then
返回值时发生的情况。满足,它通常类似于标准返回值。throw
拒绝延期时会发生这种情况。来自.then
处理程序或当您返回一个展开为拒绝*的 promise 时,它通常类似于抛出的标准异常。在 Angular 中,promise 异步解析,并通过 $rootScope.$evalAsync(callback);
解析来提供保证。 (取自 here )。
因为它是通过 $evalAsync
运行的我们知道,在 promise 解决后(通常)至少会发生一个摘要周期,因为如果没有进行中,它将安排一个新的摘要。
这也是为什么,例如,当您想要在 Angular 中对 Promise 代码进行单元测试时,您需要运行摘要循环(通常,通过 rootScope
在 $rootScope.digest()
上运行),因为 $evalAsync 执行是摘要循环的一部分。
注意:这显示了 Angular 1.2 中的代码路径,Angular 1.x 中的代码路径都是相似的,但在 1.3+ $q 中已被重构为使用原型(prototype)继承,因此这个答案不是这些版本的代码是准确的(但精神上是准确的)。
1) 当 $q 创建时,它会 this :
this.$get = ['$rootScope', '$exceptionHandler', function($rootScope, $exceptionHandler) {
return qFactory(function(callback) {
$rootScope.$evalAsync(callback);
}, $exceptionHandler);
}];
这又会:
function qFactory(nextTick, exceptionHandler) {
并且仅解析 nextTick
传递为$evalAsync
内部解析并通知:
resolve: function(val) {
if (pending) {
var callbacks = pending;
pending = undefined;
value = ref(val);
if (callbacks.length) {
nextTick(function() {
var callback;
for (var i = 0, ii = callbacks.length; i < ii; i++) {
callback = callbacks[i];
value.then(callback[0], callback[1], callback[2]);
}
});
}
}
},
在根范围内,$evalAsync 定义为:
$evalAsync: function(expr) {
// if we are outside of an $digest loop and this is the first time we are scheduling async
// task also schedule async auto-flush
if (!$rootScope.$$phase && !$rootScope.$$asyncQueue.length) {
$browser.defer(function() {
if ($rootScope.$$asyncQueue.length) {
$rootScope.$digest();
}
});
}
this.$$asyncQueue.push({scope: this, expression: expr});
},
$$postDigest : function(fn) {
this.$$postDigestQueue.push(fn);
},
正如您所看到的,如果我们不在其中并且之前没有安排过摘要,则确实会安排摘要。然后它将函数推送到 $$asyncQueue
。
依次在 $digest 内(在一个周期期间,以及在测试观察者之前):
asyncQueue = this.$$asyncQueue,
...
while(asyncQueue.length) {
try {
asyncTask = asyncQueue.shift();
asyncTask.scope.$eval(asyncTask.expression);
} catch (e) {
clearPhase();
$exceptionHandler(e);
}
lastDirtyWatch = null;
}
因此,正如我们所看到的,它运行在 $$asyncQueue
上直到它为空,执行你的 promise 中的代码。
因此,正如我们所看到的,更新范围只是简单地分配给它,如果摘要尚未运行,则摘要将运行,如果已运行,则 promise 内的代码将在 $evalAsync
上运行在观察者运行之前调用。很简单:
myPromise().then(function(result){
$scope.someName = result;
});
足够了,保持简单。
* 注意 Angular 区分抛出和拒绝 - 默认情况下记录抛出,必须显式记录拒绝
关于AngularJS : $q -> deferred API order of things (lifecycle) AND who invokes digest?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23363014/
我有以下代码: Public Delegate Sub SetStatusBarTextDelegate(ByVal StatusText As String) Private Sub SetStat
在调用 Invoke-RestMethod 时使用 Powershell,例如: Invoke-RestMethod -Method Get -Uri "https://google.com/api/
我正在尝试将 Winform 应用程序转换为控制台应用程序。 Winform 应用程序有一个委托(delegate)处理程序。如何在 console 应用程序中编写相同的功能? this.Invoke
在 WPF 中,Dispatcher.Invoke 和直接在控件实例上调用的 Invoke 有什么区别。据我了解,调度程序负责处理线程的消息,Control.Invoke 是否会继续调用 Dispat
我正在研究性能监控系统,它可以将其例程注入(inject)现有程序集。为此,我试图了解 dalvik 代码的工作原理。 下面是我要完成的工作的示例。输入类可能如下所示: class MyClass{
我正在使用 powershell 命令来执行脚本和 cmdlet。因此,在执行 cmdlet 时,我使用了 powershell.invoke,而在执行脚本时,我使用了 pipeline.invoke
有人能解释一下 Invoke-Expression $test 之间的区别吗?和 Invoke-Expression -Command $test ? 变量测试是: $test = "notepad
我有四个类,即 MapperOne、ReducerOne、MapperTwo、ReducerTwo。我想要其中的一个链。 MapperOne-->ReducerOne-->输出文件生成,输入到Mapp
我正在阅读 Java ForkJoin 框架。不直接在 ForkJoinTask 的实现上调用 invoke()(例如 RecursiveTask),而是实例化 ForkJoinPool 有什么额外的
我在调用 Invoke-SqlCmd 时遇到问题,因为它包含第二个 Invoke-SqlCmd 调用: function Get-Foo { $query=` @" WITH data AS (
有人知道如何解决这个问题吗?我创建了一个客户端来使用网络服务。客户端代码为: package cliente; import java.util.List; import handler.Header
我希望使用 P/Invoke 来允许我的 C# 程序集与 native C 库互操作;这需要是跨平台的(即 Mono),因此不能使用混合模式程序集。我想知道使用不安全的 P/invoke 调用并在不安
一般来说,我对使用 Invoke-RestMethod/Invoke-WebRequest 比较陌生 - 我认为这是以下问题的重要背景。 我正在调用如下电话: $Headers = @{ "A
在 Jenkins 的一个自由风格项目(不是说 Maven2/3 项目)中,我有两个可能的构建步骤: 调用 Maven 3 调用顶级 Maven 目标 在不同的安装中,我有不同的组合(有些两者都有,有
这是完整的错误: e: C:\Users\HP\AndroidStudioProjects\MoneyManager\app\src\main\java\com\cruxrepublic\moneym
我正在编写 jQuery 插件并将它们与 AJAX 集成。我正在减少脂肪并专注于基础知识: (function($) { function MyPlugin(el, options) {
有人可以建议我如何处理这条消息吗? CA1060 Move P/Invokes to NativeMethods class Because it is a P/Invoke method, 'UCo
在java中我们可以“用类名调用一个静态方法”也可以“用一个对象调用一个静态方法”java中“用类名调用静态方法”和“用对象调用静态方法”有什么区别? 最佳答案 没有区别,但建议以静态方式调用 sta
尝试从对话框中的 EditText 获取 Edit Text 的值,但一次又一次地出现此错误 Attempt to invoke virtual method 'android.text.Editab
我正在开发一款扑翼应用程序。在出现此错误之前,读取和写入FireStore数据库没有任何问题,但随后突然出现错误(如下所示),并阻止我读取或写入数据库。我一直在寻找答案,但不幸的是,我找不到任何可以解
我是一名优秀的程序员,十分优秀!