如何在 Angular 中使用 Bluebird?

IT技术 javascript angularjs promise bluebird angular-promise
2021-02-09 17:01:52

我尝试将 Angular 与 Bluebird Promise一起使用:

HTML:

<body ng-app="HelloApp">
    <div ng-controller="HomeController">{{name}} {{also}}</div>
</body>

JS:

// javascript
var app = angular.module('HelloApp', []);

app.controller("HomeController", function ($scope) {
    var p = Promise.delay(1000).then(function () {
        $scope.name = "Bluebird!";
        console.log("Here!", $scope.name);
    }).then(function () {
        $scope.also = "Promises";
    });
    $scope.name = "$q";
    $scope.also = "promises";
});

window.app = app;

[小提琴]

但是,无论我尝试什么,它一直停留"$q promises"并且没有更新。除非我添加了一本$scope.$apply我宁愿避免的手册

如何让 Bluebird 与 AngularJS 一起工作?

(我知道这是可能的,因为 $q 做到了)

我正在使用我在这里得到的 Bluebird 2.0

2个回答

这是可能的,甚至很容易!

好吧,如果我们看看Angular 自己的 promises是如何工作的,我们需要将 Bluebird 带到$evalAsync某个地方以获得完全相同的行为。

如果我们这样做,两个实现都符合Promises/A+的事实意味着我们可以在$q代码和 Bluebird 代码之间进行互操作,这意味着我们可以在 Angular 代码中自由使用 Bluebird 的所有功能。

Bluebird 公开了这个功能,它的Promise.setScheduler功能是:

// after this, all promises will cause digests like $q promises.
function trackDigests(app) {
    app.run(["$rootScope",function ($rootScope) {
        Promise.setScheduler(function (cb) {
            $rootScope.$evalAsync(cb);
        });
    }]);
}

现在我们要做的就是添加一个:

trackDigests(app); 

一行var app = ...一行,一切都会按预期进行。对于奖励积分,请将 Bluebird 放入服务中,以便您可以注入它而不是在全局命名空间上使用它。

这是一个 [ Fiddle ] 说明了这种行为。

请注意,除了 Bluebird 拥有的所有功能之外$q,更重要的一个是 Bluebird不会运行$exceptionHandler,而是会自动跟踪未处理的拒绝,因此您可以throw自由使用 Bluebird Promise,Bluebird 会弄清楚它们。此外,调用Promise.longStackTraces()可以帮助调试很多。

对于任何想要使用 angular-bluebird 的人。请考虑 @JPRichardson 在github.com/jprichardson/angular-bluebird/issues/1 上的这句话“我开始相信这个库实际上是一个非常糟糕的主意。Promise.setScheduler (Bluebird) 与 Angular 的 $digest 循环有一个很多不好的影响。尤其是当你想在非 UI 代码中使用 Bluebird Promise时......就像一个数据库包装器。也许最好使用 Angular 的 $q 来处理 UI 相关代码,而在其他地方使用 Bluebird Promise?”
2021-03-19 17:01:52
有什么理由不以这种方式将 Bluebird 与 Angular 一起使用吗?我已准备好开始从 Bluebird 的 API 中受益,但我不想以后因为一些意料之外的后果而受到影响。
2021-03-26 17:01:52
@MichaelGuterl 这是一个很好的问题。是的,有。它引入了另一种依赖(维护者必须了解更多的东西——甚至可能依赖于像throw总是记录这样的破坏语义)。其次,它的较大构建大约为 12kb,这并非无关紧要。第三,$q不是针对 Bluebird 测试套件运行(反之亦然),而是针对子集(Promises/A+)对两者进行测试,因此$q在 Bluebird 中可能很难找到库错误。IMO 这些都是相当小的,我已经非常成功地将两者混合在一起,并且肯定会推荐它。收获是巨大的。
2021-04-03 17:01:52
@JimTheDev 我还没有在几个大型应用程序中经历过这种情况。当然,安排关于Promise解析的摘要会假设您通常以更新 UI 的最终目的来解决Promise - 如果不是这种情况,您无论如何都会遇到与 $q 相同的问题。
2021-04-04 17:01:52
根据您的反馈,我认为我们几乎没有理由不使用 bluebird。我今天要把它添加到我们的项目中。谢谢!
2021-04-11 17:01:52

图书馆角蓝鸟Promise内容替换$q服务用bluebird$http也穿过蓝鸟