API Docs for:
Show:

File: yui3-gallery/src/gallery-async/js/async.js

/**
 * @module gallery-async
 */
(function (Y, moduleName) {
    'use strict';
    
    var _string_complete = 'complete',
        _string_initOnly = 'initOnly',
        
        _run = {
            all: '_runAll',
            queue: '_runQueue'
        },
        
        _Array = Y.Array,
        _AsyncCommand = Y.AsyncCommand,
        _Lang = Y.Lang,
        
        _createAndRun,
        _each = _Array.each,
        _instanceOf = Y.instanceOf,
        _isArray = _Lang.isArray,
        _isFunction = _Lang.isFunction,
        _isString = _Lang.isString,
        _map = _Array.map,
        _merge = Y.merge,
        _unnest = _Array.unnest,
    
        /**
        * Asynchronous command runner class.
        * @class Async
        * @extends AsyncCommand
        * @param {Object} config Configuration Object.
        */
        _class = Y.Base.create(moduleName, _AsyncCommand, [], {
            initializer: function () {
                var me = this,
                    run = _run[me.get('mode')];
                
                if (run) {
                    me._set('fn', function (success) {
                        me[run].call(me, success, me.get('run'));
                    });
                }
            },
            /**
            * Command function for all mode.
            * @method _runAll
            * @param {Function} success
            * @param {[AsyncCommand]} run
            * @protected
            */
            _runAll: function (success, run) {
                var commandCount = run.length,
                    completeCount = 0,
                    value = [];

                _each(run, function (asyncCommand, index) {
                    asyncCommand.run().after(_string_complete, function (eventFacade) {
                        if (eventFacade.failed) {
                            success.fail(eventFacade.error);
                            return;
                        }

                        completeCount += 1;
                        value[index] = eventFacade.value;

                        if (completeCount === commandCount) {
                            success(value);
                        }
                    });
                });

                if (!commandCount) {
                    success(value);
                }
            },
            /**
            * Command function for queue mode.
            * @method _runAll
            * @param {Function} success
            * @param {[AsyncCommand]} run
            * @param {Number} index
            * @param {Array} value
            * @protected
            */
            _runQueue: function (success, run, index, value) {
                index = index || 0;
                value = value || [];

                if (index >= run.length) {
                    success(value);
                    return;
                }

                run[index].run().after(_string_complete, function (eventFacade) {
                    if (eventFacade.failed) {
                        success.fail(eventFacade.error);
                        return;
                    }

                    value[index] = eventFacade.value;

                    this._runQueue(success, run, index + 1, value);
                }, this);
            }
        }, {
            ATTRS: {
                /**
                * The inherited args attribute is protected.
                * @attribute args
                * @default []
                * @initonly
                * @protected
                * @type Array
                */
               /**
                * A config object passed to the AsyncCommand constructor when
                * instantiating dynamically.
                * @attribute config
                * @default {}
                * @initonly
                * @type Object
                */
                config: {
                    value: {},
                    writeOnce: _string_initOnly
                },
                /**
                * The inherited ctx attribute is protected.
                * @attribute ctx
                * @initonly
                * @protected
                */
                /**
                * The inherited fn attribute is protected.
                * @attribute fn
                * @initonly
                * @protected
                * @type Function
                */
                /**
                * Value indicating the run mode.  Possible modes are:
                * <dl>
                *     <dt>
                *         all
                *     </dt>
                *     <dd>
                *         This mode runs all commands.  The commands might be
                *         completed out of order.  The run completes once all
                *         commands have completed.  The run fails if any command
                *         fails.
                *     </dd>
                *     <dt>
                *         queue
                *     </dt>
                *     <dd>
                *         This mode runs one command at a time.  It waits for
                *         the first command to complete before moving on to the
                *         next one.  The run completes when the last command has
                *         completed.  The run fails if a command fails and the
                *         remaining commands are not run.
                *     </dd>
                * </dl>
                * @attribute mode
                * @default 'queue'
                * @initonly
                * @type String
                */
                mode: {
                    value: 'queue',
                    writeOnce: _string_initOnly
                },
                /**
                * An array of AsyncCommands to run.  Command functions,
                * AsyncCommand config objects, and named command strings will
                * get converted to instances of AsyncCommand.
                * @attribute run
                * @default []
                * @initonly
                * @type [AsyncCommand]
                */
                run: {
                    setter: function (run) {
                        var config = this.get('config');
                        
                        return _map(_isArray(run) ? run : [
                            run
                        ], function (item) {
                            if (_instanceOf(item, _AsyncCommand)) {
                                return item;
                            }
                            
                            if (_isString(item)) {
                                item = _class.commands[item] || {};
                            }
                            
                            if (_isFunction(item)) {
                                return new _AsyncCommand(_merge(config, {
                                    fn: item
                                }));
                            }
                            
                            return new _AsyncCommand(_merge(config, item));
                        });
                    },
                    value: [],
                    writeOnce: _string_initOnly
                }
            },
            /**
             * This is a static object that stores named command definitions for
             * repeat use.  This object's keys are the names of commands.  The
             * values can either command functions or AsyncCommand config
             * objects.
             * @property commands
             * @static
             * @type Object
             */
            commands: {},
            /**
            * Creates and runs an instance of Async in 'all' mode.  This method
            * accepts an unlimited number of arguments.  Arguments can be
            * command functions, AsyncCommand config objects, instances of
            * AsyncCommand, instances of Async, or arrays containing any of the
            * above.
            * @method runAll
            * @return {Async}
            * @static
            */
            runAll: function () {
                return _createAndRun({}, 'all', _unnest(arguments));
            },
            /**
            * Creates and runs an instance of Async in 'all' mode.  This method
            * accepts an unlimited number of arguments.  The first argument is a
            * config object passed to the AsyncCommand constructor when
            * instantiating dynamically.  The rest of the arguments can be
            * command functions, AsyncCommand config objects, instances of
            * AsyncCommand, instances of Async, or arrays containing any of the
            * above.
            * @method runAllWithConfig
            * @return {Async}
            * @static
            */
            runAllWithConfig: function () {
                var args = _Array(arguments);
                
                return _createAndRun(args.shift(), 'all', _unnest(args));
            },
            /**
            * Creates and runs an instance of Async in 'queue' mode.  This
            * method accepts an unlimited number of parameters.  Parameters can
            * be command functions, AsyncCommand config objects, instances of
            * AsyncCommand, instances of Async, or arrays containing any of the
            * above.
            * @method runQueue
            * @return {Async}
            * @static
            */
            runQueue: function () {
                return _createAndRun({}, 'queue', _unnest(arguments));
            },
            /**
            * Creates and runs an instance of Async in 'queue' mode.  This
            * method accepts an unlimited number of parameters.  The first
            * argument is a config object passed to the AsyncCommand constructor
            * when instantiating dynamically.  The rest of the arguments can
            * be command functions, AsyncCommand config objects, instances of
            * AsyncCommand, instances of Async, or arrays containing any of the
            * above.
            * @method runQueueWithConfig
            * @return {Async}
            * @static
            */
            runQueueWithConfig: function () {
                var args = _Array(arguments);
                
                return _createAndRun(args.shift(), 'queue', _unnest(args));
            }
        });
    
    _createAndRun = function (config, mode, run) {
        return new _class({
            config: config,
            mode: mode,
            run: run
        }).run();
    };
    
    Y.Async = _class;
}(Y, arguments[1]));