Skip to content

Instantly share code, notes, and snippets.

@magcius
Created April 12, 2012 23:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save magcius/2371787 to your computer and use it in GitHub Desktop.
Save magcius/2371787 to your computer and use it in GitHub Desktop.
(function(exports) {
const Gio = imports.gi.Gio;
const Soup = imports.gi.Soup;
const Mainloop = imports.mainloop;
function Deferred() {
this.callbacks = [];
this.valuePair = null;
}
function spin(funcPair, valuePair) {
var cb = funcPair[0], eb = funcPair[1];
var V = valuePair[0], E = valuePair[1];
if (cb && V !== undefined) {
try {
return [cb(V), null];
} catch(e) {
E = e;
}
}
if (eb && E !== undefined) {
try {
return [eb(E), null];
} catch(e) {
return [null, e];
}
}
// Should never be reached.
return null;
}
Deferred.prototype.addCallbacks = function(cb, eb) {
var funcPair = [cb, eb];
this.callbacks.push(funcPair);
if (this.valuePair !== null)
this.valuePair = spin(funcPair, this.valuePair);
};
Deferred.prototype.addCallback = function(cb) {
return this.addCallbacks(cb, null);
};
Deferred.prototype.addErrback = function(eb) {
return this.addCallbacks(null, eb);
};
Deferred.prototype.callback = function(value) {
var i;
var funcPair, valuePair = [value, null];
if (this.valuePair !== null)
return;
for (i = 0; i < this.callbacks.length; i++) {
funcPair = this.callbacks[i];
valuePair = spin(funcPair, valuePair);
}
this.valuePair = valuePair;
};
function success(value) {
var d = new Deferred();
d.callback(value);
return d;
}
function maybeDeferred(D) {
if (D instanceof Deferred)
return D;
else
return success(D);
}
function gatherResults(deferreds) {
function maybeFinish(i, result) {
results[i] = result;
finished++;
if (finished == deferreds.length)
deferred.callback(results);
}
var i, deferred = new Deferred();
var results = [];
var finished = 0;
for (i = 0; i < deferreds.length; i++) {
results.push(null);
deferreds[i].addCallback(maybeFinish.bind(null, i));
}
return deferred;
}
const _httpSession = new Soup.SessionAsync();
function getPage(url) {
var d = new Deferred();
var message = new Soup.Message.new('GET', url);
_httpSession.queue_message(message, function(session, message) {
var contents = message.response_body.data;
d.callback(contents);
});
return d;
}
function cat(filename) {
var d = new Deferred();
var f = Gio.file_new_for_path(filename);
f.load_contents_async(null, function(f, res) {
var contents = f.load_contents_finish(res)[1];
d.callback(contents);
});
return d;
}
function sleep(ms) {
var d = new Deferred();
Mainloop.timeout_add(ms, function() {
d.callback(null);
});
return d;
}
function _step(generator, result) {
var d = generator.send(result);
d.addCallback(function(result) { _step(generator, result); });
}
function step(generator) {
return _step(generator());
}
function example() {
step(function() {
yield sleep(1000);
var pages = yield gatherResults([
getPage('http://google.com'),
getPage('http://yahoo.com'),
cat('deferred.js')
]);
log(pages);
});
Mainloop.run('');
}
// example();
exports.Deferred = Deferred;
exports.success = success;
exports.maybeDeferred = maybeDeferred;
exports.gatherResults = gatherResults;
exports.getPage = getPage;
exports.cat = cat;
exports.sleep = sleep;
})(window || exports);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment