【问题标题】:Promise Chaining承诺链
【发布时间】:2016-03-31 18:30:06
【问题描述】:

您好,我正在尝试在我的 Angular 项目中使用 q-library 实现 Promise Chaining,下面是我的 2 种方法及其链接方式。我还发布了方法实现以了解我的问题。现在在pathUserDataFromAuthService 方法中,我想使用setEtag() 方法访问我在第一个Promise 中设置的Etag 值,即getUserDataFromAuthServer,这里的问题是getEtag() 方法在第一个承诺数据被解决之前被调用。

如何确保出现正确的 Etag 值

在这方面的任何帮助都会很棒

  getUserDataFromAuthServer(user)
            .then(pathUserDataFromAuthService(user))

方法代码如下

    getUserDataFromAuthServer = function(user){
                    var defer=$q.defer();
                    $http.get(autherizationURL+'/'+'api/users/'+user.username)
                   .then(function(response){
                        var ETag =response.headers().etag;
                        console.log("etag"+ETag)
                        setEtag(ETag)
                        console.log("Etag Set changed");
                        defer.resolve(response.data);
                    },function(error){          
                          defer.reject(error.statusText);
                    });
                    return defer.promise;       
                };



            var pathUserDataFromAuthService = function (user){      
                var defer=$q.defer();
                var passwordtobesaved ={
                        "firstName": user.firstName,
                        "lastName": user.lastName
                    };
                var tag = getEtag();
            $http.put(autherizationURL+'/'+'api/users/'+user.username,passwordtobesaved,{
                    headers:{
                        "If-Match": tag
                    }
                }).then(function(response){

                    defer.resolve(response.data);
                },function(error){          
                      defer.reject(error.statusText);
                });
                return defer.promise;       
            };

【问题讨论】:

标签: angularjs promise angular-promise


【解决方案1】:

不需要使用 defer,这是一种反模式。 您可以通过返回 http 请求来简单地传递承诺。

应该是这样的:

getUserDataFromAuthServer = function(user){
  return $http.get(autherizationURL+'/'+'api/users/'+user.username)
      .then(function(response){
           var ETag =response.headers().etag;
           console.log("etag"+ETag)
           setEtag(ETag)
           console.log("Etag Set changed");
           return response.data;
        }
};

同样的事情可以在你的第二个函数中完成,虽然我不明白为什么需要它,因为它结束时你什么都不做。

var pathUserDataFromAuthService = function (user){      
  var passwordtobesaved ={
    "firstName": user.firstName,
    "lastName": user.lastName
  };
  var tag = getEtag();
  return $http.put(
    autherizationURL + '/' + 'api/users/' + user.username, 
    passwordtobesaved, 
    { headers: { "If-Match": tag } }
  )
};

【讨论】:

  • 我正在使用第一个请求中的 Etag,在将其发布到服务器时我需要 Etag 值,以便服务器对对象进行乐观锁定
  • 我也添加了第二个函数
  • 你必须使用throw error.statusText(即使拒绝/抛出字符串本身就是一种反模式)
  • @AsafDavid:是的,OP 拥有的deferrerd.reject 相当于throw
  • @AsafDavid:如果您省略错误处理程序,则结果承诺将被拒绝,原因与调用 then 的原因相同。它只是冒泡。
【解决方案2】:

正如已经指出的,主要问题是then() 接受函数

在那之后,需要传递user 让事情变得有点尴尬,但没有什么是 javascript 无法处理的。

许多方法都是可能的。这里有两个。

1.分别通过useretag,借助.bind()

这可能不是很明显,因为useretag 这两个参数是通过不同的机制传递的:

  • user: 被“绑定”
  • etag:由promise链传递给.bind()返回的函数
getUserDataFromAuthServer(user).then(pathUserDataFromAuthService.bind(null, user));

getUserDataFromAuthServer = function(user) {
    return $http.get(autherizationURL + '/api/users/' + user.username).then(function(response) {
        return response.headers().etag;
    });
};

var pathUserDataFromAuthService = function(user, etag) {
    return $http.put(autherizationURL + '/api/users/' + user.username, {
        "firstName": user.firstName,
        "lastName": user.lastName
    }, {
        headers: { "If-Match": etag }
    }).then(function(response) {
        return response.data;
    });
};

2。将useretag 作为单个对象的属性传递

这可能更直观。承诺链将单个对象作为data 传递给pathUserDataFromAuthService

getUserDataFromAuthServer(user).then(pathUserDataFromAuthService);

getUserDataFromAuthServer = function(user) {
    return $http.get(autherizationURL + '/api/users/' + user.username).then(function(response) {
        return {
            user: user,
            etag: response.headers().etag
        };
    });
};

var pathUserDataFromAuthService = function(data) {
    return $http.put(autherizationURL + '/api/users/' + data.user.username, {
        "firstName": data.user.firstName,
        "lastName": data.user.lastName
    }, {
        headers: { "If-Match": data.etag }
    }).then(function(response) {
        return response.data;
    });
};

在这两种解决方案中 setEtag() / getEtag() 消失的假设是它们存在(在问题中)仅作为传递 ETag 的机制。如果出于其他原因(例如副作用)有必要,可以重新引入它们而不会产生任何后果(除非它们抛出)。

【讨论】:

    猜你喜欢
    • 2012-07-17
    • 2015-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-15
    • 2023-03-26
    • 2023-01-27
    相关资源
    最近更新 更多