Angular:使用$ q.all进行可选promise?

时间:2019-05-11 14:23:54

标签: angularjs angular-promise

我将代码重构为干净的代码,没有重复的代码。 但是我想知道在我的情况下使用$q.all是否是最好的选择...

代码逻辑:

  • 我有一个“可选”承诺。在一种情况下,我需要调用一个外部API(= promise),在另一种情况下,我不需要该外部调用(= no promise)。
  • 因此,我创建了一个变量,可以在其中存储承诺(对于没有承诺的方案,可以存储null。)
  • $q.all等待诺言,然后检查返回值是诺言(场景1)还是null(场景2)返回的值。

重构前的功能

model.updateWish = function(wish) {
        var defer = $q.defer();

        if (wish.image) {
            // Rename temporary image.public_id to wish_id
            cloudinaryService.renameImage(wish.image.public_id, wish._id,
              function (image) {
                // Update wish with renamed image
                wish.image = image;
                $http.put(URLS.WISH + "/" + wish._id, wish).success(function (wish) {
                    updateWishlist(wish);
                    defer.resolve(wish);
                    console.info("wish updated", wish);
                });
            });
        } else {
            $http.put(URLS.WISH + "/" + wish._id, wish).success(function (wish) {
                updateWishlist(wish);
                defer.resolve(wish);
                console.info("wish updated", wish);
            });
        }
        return defer.promise;
    }

重构后的代码

model.updateWish = function(wish) {
        var defer = $q.defer();

        var renamedImagePromise = null;
        if (wish.image) {
            // Rename temporary image.public_id to wish_id
            renamedImagePromise = cloudinaryService.renameImage(wish.image.public_id, wish._id)
              .then( function (image) {
                // Update wish with renamed image
                wish.image = image;
                return wish;
            });
        }
        // Wait until renameImagePromise is resolved and send updated wish to server
        $q.all([renamedImagePromise]).then(function(wishWithRenamedImage){
            if (wishWithRenamedImage[0]) { // $q.all returns an array, wish is in "wishWithRenamedImage[0]"
                wish = wishWithRenamedImage[0];
            }
            $http.put(URLS.WISH + "/" + wish._id, wish).success(function (wish) {
                updateWishlist(wish);
                defer.resolve(wish);
                console.info("wish updated", wish);
            });
        })
        return defer.promise;
    }

这两个函数都可以,但是我想知道这是否是满足我要求的最佳实现...

1 个答案:

答案 0 :(得分:2)

使用$q.when并避免使用deferred anti-pattern

wish

更新

出于谨慎考虑,我修改了代码以克隆location对象。当对象引用传递给JavaScript函数时,该函数可以使该对象发生突变。使用函数式编程的最佳实践,应避免更改对象。