在Angular.js中实现承诺时如何始终运行一些代码


83

在我的Angular.js应用程序中,我正在运行一些异步操作。在开始之前,我先使用模式div覆盖应用程序,然后在操作完成后,无论操作是否成功,都需要删除div。

目前我有这个:

LoadingOverlay.start(); 
Auth.initialize().then(function() {
    LoadingOverlay.stop();
}, function() {
    LoadingOverlay.stop(); // Code needs to be duplicated here
})

它运作良好,但是我更喜欢这样的伪代码:

LoadingOverlay.start(); 
Auth.initialize().finally(function() { // *pseudo-code* - some function that is always executed on both failure and success.
    LoadingOverlay.stop();
})

我认为这是一个很普遍的问题,所以我想可以做到,但是在文档中找不到任何东西。知道是否可以做到吗?


如果你能链中的一个then(),那么你一定能链中的另一个... .initialize().then(...).then(...)。没有这样的“最终”。最后的处理程序是指定的最后一个处理程序。
甜菜根-甜菜根

2
@ Beetroot-Beetroot,它将无法工作,因为如果initialize()失败,则仍需要声明“成功”函数和“失败”函数,并在那里重复代码。
laurent

是行不通的,还是行不通的?
甜菜根-甜菜根

1
洛朗(Laurent),Angular的轻量级$ q服务当前没有提供您想要的东西,该服务仅通过一种方法提供承诺,.then()请参见此处的“ Promise API” 。唯一的自由是拥有一个.then()或链接多个.then()s。您并不是第一个希望获得更广泛的Promise API的人-此处正式请求您想要的功能。
甜菜根-甜菜根

1
显然always(callback)没有实现或回退角度1.2.6。我们现在必须使用finally。我不知道为什么保留字finally比保留字更好always
Aleyna

Answers:


164

该功能已在此拉取请求中实现,现已成为AngularJS的一部分。它最初被称为“ always”,后来被重命名为finally,因此代码应如下所示:

LoadingOverlay.start(); 
Auth.initialize().then(function() {
    // Success handler
}, function() {
    // Error handler
}).finally(function() {
    // Always execute this on both error and success
});

请注意,由于这finally是一个保留关键字,因此可能有必要将其设置为字符串,以使其在某些浏览器(例如IE和Android浏览器)上不会中断:

$http.get('/foo')['finally'](doSomething);

10
对于通过网络搜索发现此问题的任何人,答案中的链接都引用了该函数,always但该链接已更改finally为您在此提交(或在源代码中)中看到的:github.com/angular/angular.js/commit/…
奥斯丁汤普森2014年

@AustinThompson,感谢您提供信息,我已经更新了帖子。
劳伦特

@ this.lau_是否finally()必须是链中的最后一个调用,还是可以从中链出更多的then()?
布莱恩(Brian)

2
先生,我过得愉快!
JacobF 2014年

4
@Brianfinally和其他人一样返回一个承诺,因此您可以将其链接起来。但是(至少在Angular的某些版本上)方便性重载success并且error仅添加到的立即返回中$http,因此,如果从头开始finally则会丢失这些方法。
drzaus

7

我正在将Umbraco版本7.3.5后端与AngularJS版本1.1.5结合使用,并找到了该线程。当我执行批准的答案时,出现错误:

xxx(...)。then(...)。最终不是函数

但是,确实起作用了always。如果使用旧版AngularJS的其他人找到了该线程,而无法使用,请finally改用此代码

LoadingOverlay.start(); 
Auth.initialize().then(function() {
    // Success handler
}, function() {
    // Error handler
}).always(function() {
    // Always execute this on both error and success
});

2

对于那些不使用angularJS的用户,如果可以捕获错误(不确定.finally()是否会这样做),则可以使用.catch()。then()来避免重复的代码。

Promise.resolve()
  .catch(() => {})
  .then(() => console.log('finally'));

不管怎样,catch()可能最终对于日志记录或其他清理很有用。 https://jsfiddle.net/pointzerotwo/k4rb41a7/


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.