Skip to content

Instantly share code, notes, and snippets.

@Infocatcher
Last active December 10, 2015 02:38
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 Infocatcher/4368707 to your computer and use it in GitHub Desktop.
Save Infocatcher/4368707 to your computer and use it in GitHub Desktop.
Run special function pseudo synchronously using "yield" https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.7#Generators
sync(f);
function sync(f) {
var g = f.__generator = f();
g.next();
}
function f() {
var res;
_log("Start first async...");
setTimeout(function() {
res = 1;
f.__generator.next();
}, 2000);
yield;
_log("First async done: " + res + "\nStart second async...");
setTimeout(function() {
++res;
f.__generator.next();
}, 2000);
yield;
_log("Second async done: " + res);
yield;
}
function _log(s) {
s = "[yield] " + ts() + " " + s;
if("Services" in window && "console" in Services)
Services.console.logStringMessage(s);
else if("console" in window && "log" in console)
console.log(s);
else
setTimeout(function() { throw new Error(s); }, 0);
}
function ts() {
var d = new Date();
var ms = d.getMilliseconds();
return d.toLocaleFormat("%M:%S:") + "000".substr(String(ms).length) + ms;
}
trySync(f, 0);
trySync(f, 1);
trySync(f, 2);
function trySync(f, i) {
if(sync(f))
_log("Ok: " + i);
else
_log("Fail: " + i);
}
function sync(f) {
if("__inProgress" in f) {
_log("Previous operation aren't finished, exit!");
return false;
}
f.__inProgress = true;
var g = f.__generator = f();
g.next();
return true;
}
function cleanup(f) {
delete f.__inProgress;
delete f.__generator;
_log("Cleanup generator");
}
function f() {
var res;
_log("Start first async...");
setTimeout(function() {
res = 1;
f.__generator.next();
}, 1000);
yield;
_log("First async done: " + res + "\nStart second async...");
setTimeout(function() {
++res;
f.__generator.next();
}, 1000);
yield;
_log("Second async done: " + res);
cleanup(f);
yield;
}
function _log(s) {
s = "[yield] " + ts() + " " + s;
if("Services" in window && "console" in Services)
Services.console.logStringMessage(s);
else if("console" in window && "log" in console)
console.log(s);
else
setTimeout(function() { throw new Error(s); }, 0);
}
function ts() {
var d = new Date();
var ms = d.getMilliseconds();
return d.toLocaleFormat("%M:%S:") + "000".substr(String(ms).length) + ms;
}
sync(f, 0);
sync(f, 1);
sync(f, 2);
function sync(f/*, arg1, */) {
// Array.slice() is the same as Array.prototype.slice.call(), Firefox only
var g = f.__generator = f.apply(this, Array.slice(arguments, 1));
g.next();
}
function f(n) {
var g = f.__generator;
delete f.__generator;
var res;
_log("Start first async... #" + n);
setTimeout(function() {
res = 1;
g.next();
}, 1000);
yield;
_log("First async done: " + res + "\nStart second async... #" + n);
setTimeout(function() {
++res;
g.next();
}, 1000);
yield;
_log("Second async done: " + res + " #" + n);
yield;
}
function _log(s) {
s = "[yield] " + ts() + " " + s;
if("Services" in window && "console" in Services)
Services.console.logStringMessage(s);
else if("console" in window && "log" in console)
console.log(s);
else
setTimeout(function() { throw new Error(s); }, 0);
}
function ts() {
var d = new Date();
var ms = d.getMilliseconds();
return d.toLocaleFormat("%M:%S:") + "000".substr(String(ms).length) + ms;
}
sync(f);
sync(f);
sync(f);
function sync(f) {
if("__inProgress" in f) {
if(!("__pending" in f))
f.__pending = [];
var i = f.__pending.push(
function() {
delete f.__pending[i];
sync(f);
}
) - 1;
_log("Pending: " + i);
return;
}
f.__inProgress = true;
var g = f.__generator = f();
g.next();
}
function next(f) {
delete f.__inProgress;
delete f.__generator;
if("__pending" in f) for(var i in f.__pending) if(f.__pending.hasOwnProperty(i)) {
_log("Run pending: " + i);
f.__pending[i]();
return;
}
delete f.__pending;
_log("Destroy pendings");
}
function f() {
var res;
_log("Start first async...");
setTimeout(function() {
res = 1;
f.__generator.next();
}, 1000);
yield;
_log("First async done: " + res + "\nStart second async...");
setTimeout(function() {
++res;
f.__generator.next();
}, 1000);
yield;
_log("Second async done: " + res);
next(f);
yield;
}
function _log(s) {
s = "[yield] " + ts() + " " + s;
if("Services" in window && "console" in Services)
Services.console.logStringMessage(s);
else if("console" in window && "log" in console)
console.log(s);
else
setTimeout(function() { throw new Error(s); }, 0);
}
function ts() {
var d = new Date();
var ms = d.getMilliseconds();
return d.toLocaleFormat("%M:%S:") + "000".substr(String(ms).length) + ms;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment