【问题标题】:Data request is sometimes asynchronous数据请求有时是异步的
【发布时间】:2015-06-19 19:54:43
【问题描述】:

这是我今天早些时候发布的一个问题的后续。我正在经历this book on using AngularJS with Firebase,这导致我发布this question。我找到了解决方案,但我仍然不明白的是,API Documentation for a $firebaseArray 中的示例似乎没有将其作为异步请求处理。

var list = $firebaseArray(new Firebase(URL));

// add an item
list.$add({ foo: "bar" }).then(...);

// remove an item
list.$remove(2).then(...);

// make the list available in the DOM
$scope.list = list;

此外,书中的示例似乎也同步处理请求。

# Service
var buildingsUri = FIREBASE_URI + '/buildings';
var ref = new Firebase(buildingsUri);
var buildings = $firebaseArray(ref);

var getBuildings = function () {
  return buildings;
};

...
# Controller
$scope.buildings = syncArraySvc.getBuildings();

第一个示例中的$scope.list 和第二个示例中的$scope.buildings 在没有检查以确保请求已完成时,如何正确填充数据?

【问题讨论】:

  • 我假设 firebase 正在返回一个 $q 承诺。这些通常会在请求完成后更新以包含结果。当摘要运行时,视图将使用所述数据进行更新。
  • @KevinB 我想我在关注。基于documentation on the $q service from Angular$firebaseArray() 必须包装then 和其他回调才能返回请求的数据而不需要在客户端代码中进行回调,这听起来对吗?
  • 不,我很确定它只是返回一个 $q 承诺。 console.log 可以肯定的是,您应该看到的不仅仅是您的数据。它不能只更新 var 以包含其他内容,它仍将是它返回给您的任何基础对象。

标签: javascript angularjs asynchronous firebase


【解决方案1】:

$add 和 $remove 方法返回承诺。 $firebaseArray() 方法返回一个添加了一些特殊函数和属性的数组。 $add 或 $remove 都不需要本地加载数据或依赖于数据的状态,因此可以同步调用它们。当然,数据仍然是异步下载的。所以,例如:

var list = $firebaseArray(new Firebase(URL));

// add an item
list.$add({ foo: "bar" }).then(function(ref) {
   console.log('added', ref.key());
});

// remove an item
list.$remove(2).then(function(ref) {
   console.log('removed', ref.key());
});

console.log('list current contains', list.length, 'items');

list.$loaded(function() {
   console.log('after loading initial data, the list contains', list.length, 'items');
});

假设列表在加载时包含 10 个项目,并且在此代码执行期间没有远程更改该列表,我们将看到类似于以下的输出:

list currently contains 0 items
after loading initial state, the list contains 10 items
added abc123
removed xyz456

另外,我注意到这段代码可能是多余的。通常当我们看到这样的代码时,是因为开发人员正试图将 Firebase 变成一个 CRUD 模型。您可能只需要在此处返回 $firebaseArray() 并使用现有的方法,例如 $getRecord() 等,而不是在您的服务中人为地包装 API。

【讨论】:

  • In a related question,有人评论说使用console.log调试AngularFire数据不是一个好主意。我了解$add$remove 方法,因为它们使用标准的promise 语法和.then。在您的示例中,您使用$loadedlist,但是如果您将list 分配给范围,例如使用$scope.list = list,它将正确呈现列表项。即使在该赋值之后放置console.log 也会返回一个空数组。这就是我没有得到的。
  • 数据下载到本地后为空。此外,在 1.1.0 和 1.1.1 版本中使用 $extend 时,$loaded 方法中存在错误。它已在 1.1.2 中修复
猜你喜欢
  • 2012-02-25
  • 2017-11-06
  • 1970-01-01
  • 2018-02-11
  • 1970-01-01
  • 2016-05-04
  • 1970-01-01
  • 2020-07-21
相关资源
最近更新 更多