从 $resource.get(...).$promise 中提取数据

Extract data from $resource.get(...).$promise

我使用 $resource 从 Facebook 的 Graph api 获取数据:

resource = $resource(
    "https://graph.facebook.com/v2.2/:api/:id/:node/"
)

例如,我通过以下方式向“https://graph.facebook.com/v2.2/user.id/albums/”发出了成功的请求:

resource.get({id:user_id, node: "albums", access_token: ....}).then(function(response)
{
    console.log(response)
})

并且响应显示(在 Chrome 开发工具控制台中):

Resource
- $promise: Promise
- $resolved: true
- data: Array[9] 
    - 0: Object
    - 1: Object2:
    - length: 9
    - __proto__: Array[0]
- paging: Object
- __proto__: Resource

所以我天真地尝试在 console.log response 下添加另一个 console.log response.data,

但它显示 'undefined'。

所以我想知道如何提取 data 对象?

========================== 编辑 ======== ================

看来原因是

resource.get({id:user_id, node: "albums", access_token: ....}).then(function(response)
{
    console.log(response)
})

在另一个资源请求之后链接如下:

    FB.get_user().then(function(response) {
  var user_id;
  return user_id = response.id;
}).then(function(response) {
  return self.albums = FB.resource.get({
    id: user_id,
    node: "albums",
    access_token: Auth.get_user().social_account_access_token
  });
}).then(function(response) {
  console.log("response", response); # Log #1
  return console.log("response.data", response.data); # Log #2
});

在这种情况下,Log #1 将注销 resource 对象,其中 data 是一个数组,而 Log #2 给出 undefined.

如果我不链接 then 函数,而是将最后一个放在前一个 .then 中,我会得到预期的结果:

FB.get_user().then(function(response) {
  var user_id;
  return user_id = response.id;
}).then(function(response) {
  return self.albums = FB.resource.get({
    id: user_id,
    node: "albums",
    access_token: Auth.get_user().social_account_access_token
  }).$promise.then(function(response) {
    console.log("A: response", response);  # Log #1
    return console.log("response.data", response.data); # Log #2
  });
});

给出 Log #1 相同的结果,而 Log #2 是一个包含 9 个元素的数组。

**所以我怀疑是不是我原来方法的问题?**


您第一次尝试时发生的情况是,在您第二次 then() 中,您正在 return 计算 FB.resource.get() 的 return 值,但此值不是承诺,因此此 then() 会立即解析,并且在数据检索完成之前处理会移至下一个 then()。当您在 Chrome 调试器中查看值时,您将停止执行足够长的时间以使请求完成,并且当您观察到数据时会填充数据。 (顺便说一句,有一个term for this phenomenon。)

根据 this pull request and this note in the developer's guide 上的说明,如果您想链接资源请求,您应该使用 instance.$promise。因此,您使用 $promise 的第二种方法或多或少是正确的方法。

您的代码可以稍微清理一下。除非你有理由想要一个单独的步骤来提取 FB 用户 ID 并将其传递给下一步,否则你可以删除第一个 .then()。您还可以做一些其他整理工作:

FB.get_user()
.then(function (response) {
    var user_id = response.id;
    // the value assigned to self.albums here is a (mostly) empty object that will 
    // be populated with data when the request finishes
    self.albums = FB.resource.get({
        id: user_id,
        node: "albums",
        access_token: Auth.get_user().social_account_access_token
    });
    return self.albums.$promise;
})
.then(function (response) {
    // (avoid putting a [then] inside another [then] unless you need to)
    console.log("A: response", response);
    console.log("response.data", response.data);
    return response.data;
});