angular js结合异步和同步代码

angular js combine asynchronous and synchronous code

我正在使用 angular resource 模块与我的 restfull 网络服务器一起工作。例如,我有一个方法 return 是一个包含 10 个元素的数组,我想做的只是将结果保存到一些 javascript 变量中( 不在 angular 范围内) 称为 books.

所以我写了一个简单的方法,看起来像这样:

function getBooks(user_id) {
    var books = [];
    BookFactory.getBooks.query({ id: user_id }).$promise.then(function (result) {
        angular.forEach(result, function(i) {
            books.push(i);
        });
    });
    return books;
}

让我们假设 BookFactory.getBooks.query 按预期工作并且确实 returns 10 个元素。 所以这个函数内部有一个简单的逻辑,我只是​​将每个元素推送到数组 books.

我还有一个测试函数,用于测试 getBooks() 功能。在这里:

$scope.testGetBooksMethod = function (user_id) {
    var resut = getBooks(user_id);
    alert(resut.length);
};

alert 中的结果将始终为 0。我知道这部分代码:

BookFactory.getBooks.query({ id: user_id }).$promise.then(function (result) {
            angular.forEach(result, function(i) {
                books.push(i);
            });
        });

异步工作,直到处理服务器请求,函数 getBooks() returns 一个空的书籍数组(如果我错了请纠正我)。

这里有一个问题,我如何编辑我的函数,使其正常工作。我想从 rest 获取数据,用这些数据填充数组 books 然后 return 它。

提前致谢。

这里需要使用promise概念,控制器函数testGetBooksMethod会等到服务方法getBooks完成调用。为此,您需要 return 来自 getBooks 函数的 BookFactory.getBooks.query 承诺。检索数据后,书籍将被创建,并且将从 getBooks 方法中 return。在调用 getBooks 方法时,您需要使用 .then 函数来继续链式承诺,当数据从 getBooks 中 return 编辑时,此函数将获取数据 return来自您的服务。

function getBooks(user_id) {
    var books = [];
    return BookFactory.getBooks.query({ id: user_id }).$promise.then(function (result) {
        angular.forEach(result, function(i) {
            books.push(i);
        });
        return books;
    });
}

控制器

$scope.testGetBooksMethod = function (user_id) {
    getBooks(user_id).then(function(resut){
        alert(resut.length);
    });
};

I want to get data from rest, fill the array books with this data and then return it.

就是这样。异步编程与同步编程并不真正兼容。所以你不能只是把它们结合起来。但是,您可以以 类似同步的 方式工作,这就是 promises 非常强大的地方。你不 return data,你 return stateful Promise object 相反。

因此,与其 returning books return 承诺 这本书 :

function getBooks(user_id) {
    return BookFactory.getBooks.query({ id: user_id }).$promise;
}

然后在使用代码时,您将使用具有底层状态控制机制的包装对象,该机制将在书籍加载并可用时继续:

$scope.testGetBooksMethod = function (user_id) {
    getBooks(user_id).then(function(books) {
        alert(books.length);
    });
};