为什么我的 $q resolve 和 promise 不像我想的那样工作?

Why doesn't my $q resolve and promise work like I think it does?

我总是遇到 $q

的问题

这里是 .then 立即触发的示例

    function doit() {
            var deferred = $q.defer();

            var modalInstance = $modal.open({
                template: '<p>this is modal</p><a ng-click="ok()">ok</a>',
                controller: function ($scope, $modalInstance) {
                    $scope.ok = function () {
                        $modalInstance.close();
                    };
                }
            });

            modalInstance.result.then(function () {
                console.log('ok');
                deferred.resolve();
            }, function () {
                console.log('Modal dismissed');
            });

            return deferred.promise;
        }

其他地方:

    $scope.service.doit().then(
                $scope.variable = 5
            );

http://jsfiddle.net/IngoVals/stqwanhm/

我在 Fiddle 中尝试对另一个类似的设置进行建模时得到了这个,其中 .then 根本没有触发。这是怎么回事?

您在此处将值 5 传递给 then

$scope.service.doit().then(
    $scope.variable = 5
);

代码 运行 是这样的:

  1. $scope.variable 被赋值为 5

  2. 赋值表达式的结果(即赋值,5)传入then

当您调用 then 时,这两种情况都会 立即发生 。他们不会等待承诺得到解决。

您想将 函数 传递给 then,并让函数设置变量:

$scope.service.doit().then(function() {
    $scope.variable = 5
});

现在你正在传递一个函数。代码 in 函数在被调用之前不会是 运行,它会在 promise 被解析时被调用。

Updated Fiddle

好消息和坏消息是,从 ES6 开始,这将变得更加简洁,因为 ES6 引入了 "fat arrow" 函数:

$scope.service.doit().then(() => $scope.variable = 5);

这还会创建一个函数并将其传递给 then(在支持 ES6 的引擎上)。

我说这既是好消息也是坏消息,因为它简洁明了(好!),而且您在阅读时也很容易错过(坏!)。 :-)

它不会立即触发,只是您在 then 回调之外更新范围 属性。此代码:

$scope.service.doit().then(
    $scope.variable = 5
);

不正确,应该是

$scope.service.doit().then(function() {
    $scope.variable = 5
});

另一个问题是所谓的deferred anti-pattern。避免创建多余的延迟对象:

function doit() {
    return $modal.open({
        template: '<p>this is modal</p><a ng-click="ok()">ok</a>',
        controller: function ($scope, $modalInstance) {
            $scope.ok = function () {
                $modalInstance.close();
            };
        }
    }).result.then(function () {
        console.log('ok');
    }, function () {
        console.log('Modal dismissed');
    });
}

演示: http://jsfiddle.net/stqwanhm/2/