如何将Bluebird与Angular一起使用?

Ben*_*aum 44 javascript promise angularjs bluebird angular-promise

我尝试使用Angular和Bluebird的承诺:

HTML:

<body ng-app="HelloApp">
    <div ng-controller="HomeController">{{name}} {{also}}</div>
</body>
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

[ 小提琴 ]

但是,不管我尝试了什么,它都会保持停留"$q promises"并且不会更新.除非我添加了一本$scope.$apply我宁愿避免使用的手册.

如何让Bluebird与AngularJS合作?

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

我正在使用Bluebird 2.0,我在这里.

Ben*_*aum 60

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

好吧,如果我们看看Angular自己的承诺是如何工作的,我们需要将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);
        });
    }]);
}
Run Code Online (Sandbox Code Playgroud)

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

trackDigests(app); 
Run Code Online (Sandbox Code Playgroud)

行后行var app = ...,一切都会按预期工作.对于奖励积分,将Bluebird放入服务中,这样您就可以注入它而不是在全局命名空间中使用它.

这是一个[ 小提琴 ]说明这种行为.

请注意,除了Bluebird已经完成的所有功能之外$q,其中一个更重要的功能是Bluebird 无法运行$exceptionHandler,而是会自动跟踪未处理的拒绝,因此您可以throw自由地使用Bluebird的承诺,Bluebird会将其弄清楚.此外,调用Promise.longStackTraces()可以帮助调试很多.

  • @MichaelGuterl 这是一个很好的问题。是的,有。它引入了另一种依赖(维护者必须了解更多的东西 - 甚至可能依赖于像 `throw` 总是记录的破坏语义)。其次,它的较大构建大约为 12kb,这并非无关紧要。第三,`$q` 不是针对 Bluebird 测试套件运行的(反之亦然),而是两者都针对一个子集(Promises/A+)进行测试,因此在 Bluebird 中可能很难找到 `$q` 库错误。IMO 这些都是相当小的,我已经非常成功地将两者混合在一起,并且肯定会推荐它。收获是巨大的。 (7认同)
  • 有没有理由不以这种方式使用Bluebird和Angular?我已经准备好开始从Bluebird的API中受益了,但是我不想因为一些意想不到的后果而后来被咬了. (5认同)