website-2018/node_modules/hbs/lib/async.js
2018-06-12 20:32:09 -04:00

109 lines
2.1 KiB
JavaScript

/// provides the async helper functionality
function Waiter() {
if (!(this instanceof Waiter)) {
return new Waiter();
}
var self = this;
// found values
self.values = {};
// callback when done
self.callback = null;
self.resolved = false;
self.count = 0;
};
Waiter.prototype.wait = function() {
var self = this;
++self.count;
};
// resolve the promise
Waiter.prototype.resolve = function(name, val) {
var self = this;
self.values[name] = val;
// done with all items
if (--self.count === 0) {
self.resolved = true;
// we may not have a done callback yet
if (self.callback) {
self.callback(self.values);
}
}
};
// sets the done callback for the waiter
// notifies when the promise is complete
Waiter.prototype.done = function(fn) {
var self = this;
self.callback = fn;
if (self.resolved) {
fn(self.values);
}
};
var alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_';
var gen_id = function() {
var res = '';
for (var i=0 ; i<8 ; ++i) {
res += alphabet[Math.floor(Math.random() * alphabet.length)];
}
return res;
};
module.exports = function() {
// baton which contains the current
// set of deferreds
var waiter;
var obj = Object.create(null);
obj.done = function done(fn) {
// no async things called
if (!waiter) {
return fn({});
}
waiter.done(fn);
// clear the waiter for the next template
waiter = undefined;
};
obj.resolve = function resolve(fn, args) {
// we want to do async things, need a waiter for that
if (!waiter) {
waiter = new Waiter();
}
var id = '__' + gen_id() + '__';
var cur_waiter = waiter;
waiter.wait();
args = [].slice.call(args);
args.push(function(res) {
cur_waiter.resolve(id, res);
})
fn.apply(null, args);
// return the id placeholder
// this will be replaced later
return id;
};
return obj;
};