【问题标题】:Understanding angular's promises理解 Angular 的承诺
【发布时间】:2014-12-03 12:35:45
【问题描述】:

我正在学习 Angular,但无法理解某个观点。我想从我的服务器获取数据。我使用了这段代码(来自 Angular 的文档):

this.myFunction = new function()
{
    var uri = this.getServerUri() + "Connexion/"+login+"/"+CryptoJS.MD5(pass);

            var promises = $http.get(uri)
            .success(function(data, status, headers, config) {
                // this callback will be called asynchronously
                // when the response is available
                //alert("success:"+JSON.stringify(data));
                return data;
            }).
            error(function(data, status, headers, config) {
                // called asynchronously if an error occurs
                // or server returns response with an error status.
                return "";
            });
            return promises;
};

但我不理解成功函数的行为。当我调用这个函数时,它工作正常,我得到了服务器的答案,但我得到了完整的 Promise 对象(我必须编写“promises.data”来获取我的数据)。你能解释一下为什么吗?因为在成功函数中我试图只返回数据。

编辑:我忘了添加我的调用函数:

var serverAccepted = this.MyFunction().then(function(promise) {
                        var objet = promise.data;
                        if(!_.isEmpty(objet))
                        {
                            userService.setUser(objet, true);
                            return "";
                        }
                        else return "Error while trying to login on the server";

                    });
        return serverAccepted;

谢谢

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    promise 是一种处理 异步 请求的方式,无需 blocking。在执行更多代码之前,不会等待缓慢的操作(例如等待服务器响应),而是返回 promise 并继续执行代码。

    因此,当您在上面的代码中调用myFunction 时,它将返回一个promise 对象。

    然后,Promise 提供了一些简洁的方法来注册回调以在服务器确实响应时运行代码。这些方法分别是成功和错误情况的.then()catch()

    将函数作为参数传递将在服务器响应时调用该函数,您可以对数据做任何您喜欢的事情。举个例子:

    console.log("About to send request");
    myFunction()
    .then( function (myData){
      console.log("Response received", myData);
    })
    .catch( function (myError){
      console.error("Oh dear", myError);
    });
    console.log("Request sent!");
    

    这会将以下内容记录到控制台:

    About to send request
    Request sent!
    Response received, {}
    

    编辑

    回应您的评论:

    为什么收到的响应包含完整的承诺对象而不仅仅是数据? 因为我在成功函数中返回数据。

    您收到的响应确实包含承诺,但您的函数返回承诺。在您的示例中,serverAccepted 被分配了 myFunction() 的返回值,这是一个承诺,不会改变

    行:

    .success(function(data, status, headers, config) {
       return data;
    })
    

    实际上并没有做任何事情 - 从 .then().success() 函数返回一个值仅在您要将多个对 .then() 的调用链接在一起时才有用 - 它提供了一种操作值的方法,而无需不断增加的嵌套回调金字塔。 从 Promise 回调(传递给 .then().success() 的函数)中返回值不会更改 Promise 本身(在您的情况下为 serverAccepted)。

    例如:

    假设您的服务器上的 http GET some/url 返回:

    {
      foo: 'bar',
      dorks: 12
    }
    

    当我们使用$http.get 时,此数据作为名为@9​​87654340@ 的字段位于响应对象内部。大多数时候我们不太关心其余的东西,如果调用成功,我们只需要数据,所以我们可以从第一个 .then() 调用(通常在你的服务中)返回它,这样任何随后的.then() 调用(例如在控制器内部)可以直接访问数据对象。

    myPromise = $http.get('some/url')
    .then( function (response) {
      console.log(response); //--> { status: 200, data: { foo:....}}
      return response.data;
    })
    .then( function (data) {
      console.log(data); //--> {foo: 'bar', dorks: 12}
      return dorks;
    })
    .then( function (data) {
      console.log(data); //--> 12
    })
    
    console.log(myPromise); //--> promise object with .then() .catch() etc
    // ^ THIS WILL NOT CHANGE.
    

    【讨论】:

    • 我明白了,但为什么收到的响应包含完整的承诺对象而不仅仅是数据?因为我在success函数中返回了数据。
    【解决方案2】:

    当我调用这个函数时,它工作正常,我得到了服务器的答案,但我得到了完整的 Promise 对象

    听起来你正在做这样的事情:

    var data = service.myFunction();
    

    以上在同步世界中会很好,但是在异步操作的情况下,这不是正确使用 Promise。相反,您应该使用返回的 promise then/success 方法:

    service.myFunction().then(function(data) {
        console.log(data);
    });
    

    【讨论】:

    • thensuccess 是否需要注入$q 并在响应上设置延迟/解析?
    • 不,$http.get() 已经返回了一个 Promise。你需要做的就是链接then/success方法,提供一个回调,一旦promise被解决,它就会被调用。
    • 我粘贴了我的调用函数,如您所见,我需要编写 'promise.data' 才能使我的代码正常工作。
    【解决方案3】:

    $http request ,返回一个带有两个 $http 特定方法的承诺:成功和错误。 success 函数等待直到请求成功完成(这意味着在$http promise 解析之后),并且error 函数只有在 $http promise 被拒绝后才会执行。

    【讨论】:

      猜你喜欢
      • 2022-01-22
      • 2015-02-22
      • 2015-12-06
      • 2017-04-04
      • 1970-01-01
      • 2017-03-18
      • 2017-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多