AngularJS +如何在运行下一个任务之前等待任务完成

时间:2016-08-08 12:13:13

标签: angularjs

我的数据库仍然存在问题,但我发现问题来自于打开数据库需要一些时间,但应用程序不会等到此任务完成。

在开始下一个任务之前,有没有办法在数据库正确打开之前进行角度等待?

谢谢, 基督教。

更新时间:2016-08-08 - 03:13 pm

感谢所有答案。我可以看到,我对promises的第一个想法($ q)是正确的,但是:

我的应用有一个app.js,这是我的主文件。它只调用InitDB。这应该打开数据库。然后它应该调用CreateTables,这会创建表,如果它不存在。

我的应用程序的其余部分分为4页(模板)。每个页面都有自己的控制器。

所以我的想法是初始化数据库,创建表,然后使用数据库,但在不同的控制器上使用。

这不起作用,因为我总是需要将我的所有东西放在我的initDB的.then()中的app.js ???

这是我的第一个AngularJS应用程序,也许这就是我犯了很多错误的原因......

谢谢, 基督教。

4 个答案:

答案 0 :(得分:1)

Angular的核心概念之一是与服务/工厂合作。关于这些如何工作以及如何使用它们的文档和博客很多,但基本的想法是这些是单例"控制器"处理整个应用程序中的共享数据和方法。与promises结合使用,您可以轻松创建一个管理与数据库通信的服务。

angular
  .module('myApp')
  .service('DBService', DBService)
  .controller('Ctrl1', Ctrl1)
  .controller('Ctrl2', Ctrl2)
  .controller('Ctrl3', Ctrl3)
  .controller('Ctrl4', Ctrl4);

DBService.$inject = ['$q'];
function DBService($q) {
  var DBService = this;
  var DBServiceDeferred = $q.defer();
  DBService.ready = DBServiceDeferred.promise;

  // a service is only initialized once, so this will only ever be run once
  (function() {
    init();
  })();

  function init() {
    // you can use promise chaining to control order of events
    // the chain will halt if any function is rejected
    initDB()
    .then(createTablesUnlessExist)
    .then(setDbReady);
  }

  function initDB() { 
    var deferred = $q.defer();
    // simulate async db initialization
    $timeout(function() {
      deferred.resolve();
      // or reject if there is an error
      // deferred.reject();
    }, 5000);
    return deferred.promise;
  };

  function createTablesUnlessExist() {
    //create tables if needed (only happens once)
    var deferred = $q.defer();
    // simulate async table creation
    $timeout(function() {
      deferred.resolve();
      // or reject if there is an error
      // deferred.reject();
    }, 5000);
    return deferred.promise;
  }

  function setDbReady() {
    DBServiceDeferred.resolve();
  }
}

现在您已经安装了数据库,您不必再担心它了。您可以使用该服务从任何控制器访问数据库。在初始化数据库并创建表之前,所有查询都不会运行。

Ctrl1.$inject = ['DBService', '$q'];
function Ctrl1(DBService, $q) {
  $q.when(DBService.ready).then(function() {
    DBService.conn.query("Select something");
  });
}
Ctrl2.$inject = ['DBService', '$q'];
function Ctrl2(DBService, $q) {
  $q.when(DBService.ready).then(function() {
    DBService.conn.query("Select something");
  });
}
Ctrl3.$inject = ['DBService', '$q'];
function Ctrl3(DBService, $q) {
  $q.when(DBService.ready).then(function() {
    DBService.conn.query("Select something");
  });
}
Ctrl4.$inject = ['DBService', '$q'];
function Ctrl4(DBService, $q) {
  $q.when(DBService.ready).then(function() {
    DBService.conn.query("Select something");
  });
}

答案 1 :(得分:0)

Angular提供服务$ q。一种服务,可以帮助您异步运行函数,并在完成处理时使用它们的返回值(或异常)。请参阅文档https://docs.angularjs.org/api/ng/service/$q以获取相同的信息。 $ q基本上围绕着承诺的概念。 AngularJS中的Promise由内置的$ q服务提供。

答案 2 :(得分:0)

编写一个方法来检查是否建立了连接...返回true或false。

app.controller('MainCtrl', function($scope, httpq) {
    http.get('server call method')
      .then(function(data) {
        if(data.conn==true)
       // do what u want
      //write other calls
      })
      .catch(function(data, status) {
        console.error('error', response.status, response.data);
      })

    });

答案 3 :(得分:0)

你可以使用$ q库

示例:

app.service("githubService", function ($http, $q) {
var deferred = $q.defer();

this.getAccount = function () {
    return $http.get('https://api.github.com/users/haroldrv')
        .then(function (response) {
            // promise is fulfilled
            deferred.resolve(response.data);
            // promise is returned
            return deferred.promise;
        }, function (response) {
            // the following line rejects the promise 
            deferred.reject(response);
            // promise is returned
            return deferred.promise;
        })
    ;
};

});

使用以上服务:

app.controller("promiseController", function ($scope, $q, githubService) {
githubService.getAccount()
    .then(
        function (result) {
            // promise was fullfilled (regardless of outcome)
            // checks for information will be peformed here
            $scope.account = result;
        },
        function (error) {
            // handle errors here
            console.log(error.statusText);
        }
    );

});