Created
April 18, 2012 02:31
-
-
Save magcius/2410703 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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) { | |
let [cb, eb] = funcPair; | |
let [V, E] = valuePair; | |
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) { | |
let 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) { | |
let valuePair = [value, null]; | |
if (this.valuePair !== null) | |
return; | |
for (let i = 0; i < this.callbacks.length; i++) { | |
let funcPair = this.callbacks[i]; | |
valuePair = spin(funcPair, valuePair); | |
} | |
this.valuePair = valuePair; | |
}; | |
function success(value) { | |
let 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); | |
} | |
let deferred = new Deferred(); | |
let results = []; | |
let finished = 0; | |
for (let 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) { | |
let d = new Deferred(); | |
let message = new Soup.Message.new('GET', url); | |
_httpSession.queue_message(message, function(session, message) { | |
let contents = message.response_body.data; | |
d.callback(contents); | |
}); | |
return d; | |
} | |
function cat(filename) { | |
let d = new Deferred(); | |
let f = Gio.file_new_for_path(filename); | |
f.load_contents_async(null, function(f, res) { | |
let [success, contents] = f.load_contents_finish(res); | |
d.callback(contents); | |
}); | |
return d; | |
} | |
function sleep(ms) { | |
let d = new Deferred(); | |
Mainloop.timeout_add(ms, function() { | |
d.callback(null); | |
}); | |
return d; | |
} | |
function _step(generator, result) { | |
let 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