strapi/lib/private/after.js
2015-10-01 00:30:16 +02:00

88 lines
2.0 KiB
JavaScript
Executable File

'use strict';
/**
* Module dependencies
*/
// Public node modules.
const _ = require('lodash');
const async = require('async');
/**
* Mix-in an `after` function to an `EventEmitter`
*
* If `events` have already fired, trigger fn immediately (with no args)
* Otherwise bind a normal one-time event using `EventEmitter.prototype.once()`.
* Useful for checking whether or not something has finished loading, etc.
*
* @param {EventEmitter} emitter
*/
module.exports = function mixinAfter(emitter) {
/**
* `emitter.warmEvents`
*
* Events which have occurred at least once
* (required to support `emitter.after()`).
*/
emitter.warmEvents = {};
/**
* `emitter.emit()`
*
* Override `EventEmitter.prototype.emit`.
* (required to support `emitter.after()`).
*/
const _emit = _.assign(emitter.emit);
emitter.emit = function (evName) {
emitter.warmEvents[evName] = true;
_emit.apply(emitter, _.slice(arguments, 0));
};
/**
* `emitter.after()`
*
* Fires your handler if the specified event
* has already been triggered or when it is triggered.
*
* @param {String|Array} events Name of the event(s)
* @param {Function} fn Event handler function
* @context {Strapi}
*/
emitter.after = function (events, fn) {
// Support a single event or an array of events.
if (!_.isArray(events)) {
events = [events];
}
// Convert named event dependencies into an array
// of async-compatible functions.
const dependencies = _.reduce(events,
function (dependencies, event) {
const handlerFn = function (cb) {
if (emitter.warmEvents[event]) {
cb();
} else {
emitter.once(event, cb);
}
};
dependencies.push(handlerFn);
return dependencies;
}, []);
// When all events have fired, call `fn`
// (all arguments passed to `emit()` calls are discarded).
async.parallel(dependencies, function (err) {
if (err) {
strapi.log.error(err);
}
return fn();
});
};
};