From fc922d3bd74975bd7012132e9386b7a5d3fe5194 Mon Sep 17 00:00:00 2001 From: mbektimirov Date: Tue, 4 Jun 2013 17:07:39 +0600 Subject: [PATCH] Implemented #172 with promises App.start now returns a promise which depends on all application widgets promisses. Just return a promise() in widget 'initialize' method to handle async loading. --- lib/aura.js | 30 +++++++++++++++++++++++++++--- lib/ext/widgets.js | 24 +++++++++++++++++------- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/lib/aura.js b/lib/aura.js index 118c049..d0656f0 100644 --- a/lib/aura.js +++ b/lib/aura.js @@ -106,6 +106,8 @@ define([ */ Aura.prototype.start = function(options) { var app = this; + var extsPromisses = []; + var appInitDfd = base.data.deferred(); if (app.started) { app.logger.error("Aura already started... !"); @@ -119,10 +121,28 @@ define([ // Then we call all the `afterAppStart` provided by the extensions base.util.each(exts, function(i, ext) { - if (ext && typeof(ext.afterAppStart) === 'function') { + if (ext) { try { - ext.afterAppStart(app); + extsPromisses.push((ext.afterAppStart || noop)(app)); + + // application is loaded when all widgets has been loaded + if (extsPromisses.length === exts.length) { // all widgets are here + base.data.when.apply(undefined, extsPromisses).then( + function () { + appInitDfd.resolve(); + }, + + function (e) { + appInitDfd.reject(); + + app.logger.error('Error in widget loading: ' + e); + } + ); + } + } catch(e) { + appInitDfd.reject(); + app.logger.error("Error on ", (ext.name || ext) , ".afterAppStart callback: (", e.message, ")", e); } } @@ -133,6 +153,8 @@ define([ // reject every body an do some cleanup // TODO: Provide a better error message to the user. app.extensions.onFailure(function() { + appInitDfd.reject(); + app.logger.error("Error initializing app...", app.config.name, arguments); app.stop(); }); @@ -141,7 +163,9 @@ define([ // to keep track of the loading process... // - return app.extensions.init(); + app.extensions.init(); + + return appInitDfd.promise(); }; /** diff --git a/lib/ext/widgets.js b/lib/ext/widgets.js index 6dc43b2..dad54d3 100644 --- a/lib/ext/widgets.js +++ b/lib/ext/widgets.js @@ -28,7 +28,8 @@ define('aura/ext/widgets', function() { this._ref = options._ref; this.$el = core.dom.find(options.el); - this.initialize.call(this, this.options); + this.options.onLoadPromise = this.initialize.call(this, this.options); + return this; } @@ -143,12 +144,20 @@ define('aura/ext/widgets', function() { var newWidget = new WidgetConstructor(options); - var initialized = core.data.when(newWidget); + core.data.when(newWidget.options.onLoadPromise).then( + function(ret) { + dfd.resolve(ret); + + app.logger.log("Widget loaded:", name, newWidget); + }, + + function(ret) { + dfd.reject(ret); + + app.logger.error("Widget not loaded:", name, newWidget); + } + ); - initialized.then(function(ret) { dfd.resolve(ret); }); - initialized.fail(function(err) { dfd.reject(err); }); - app.logger.log("Widget loaded:", name, newWidget); - return initialized; } catch(err) { app.logger.error(err.message); dfd.reject(err); @@ -292,7 +301,8 @@ define('aura/ext/widgets', function() { afterAppStart: function(app) { // Auto start widgets when the app is loaded. if (app.startOptions.widgets) { - app.core.start(app.startOptions.widgets); + // return a widget promise to handle async loading in Aura layer + return app.core.start(app.startOptions.widgets); } }