Created
December 6, 2011 03:47
-
-
Save wheeyls/1436623 to your computer and use it in GitHub Desktop.
Repeat until - a simple polling function
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
/** | |
* Poll until a test passes. | |
* When the test returns something, (not false) pass its value to and_then | |
* | |
* Example: | |
* repeat_until(function() { | |
* return "some value"; | |
* }).and_then(function(result) { | |
* console.log(result); // "some value" | |
* }).timeout(function() { | |
* console.log("timed out trying!"); | |
* }, 5000); | |
* | |
* jslint sloppy: true, white: true, maxerr: 50, indent: 2, browser: true | |
**/ | |
(function(context) { | |
var repeat_until = function(test, delay) { | |
var done = false, me, completeFn, | |
success_timer, success_callbacks = [], failure_timer, test_result, repeat; | |
delay = delay !== undefined ? delay : 20; | |
repeat = function() { | |
var i, ii; | |
test_result = test(); | |
if(test_result === false) { | |
success_timer = window.setTimeout(repeat, delay); | |
} else { | |
completeFn(test_result); | |
} | |
}; | |
completeFn = function (test_result) { | |
done = true; | |
window.clearTimeout(failure_timer); | |
for (i=0, ii = success_callbacks.length; i<ii; i+=1) { | |
success_callbacks[i](test_result); | |
} | |
}; | |
me = { | |
and_then: function(success) { | |
if(done && test_result !== false) { | |
success(test_result); | |
} else { | |
success_callbacks.push(success); | |
} | |
return me; | |
}, | |
now: function () { | |
completeFn(test_result); | |
}, | |
timeout: function(failure, time) { | |
time = time !== undefined ? time : 7000; | |
failure_timer = window.setTimeout(function() { | |
if(!done) { | |
done = true; | |
failure(); | |
window.clearTimeout(success_timer); | |
} | |
}, time); | |
return me; | |
} | |
}; | |
repeat(); | |
return me; | |
}; | |
context.repeat_until = repeat_until; | |
}(this)); |
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
<html> | |
<head> | |
<script src="http://code.jquery.com/jquery-latest.js"></script> | |
<link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css" type="text/css" media="screen" /> | |
<script type="text/javascript" src="http://code.jquery.com/qunit/git/qunit.js"></script> | |
<script src="repeat_until.js"></script> | |
<script type="text/javascript"> | |
(function() { | |
module("repeat_until", { | |
setup: function() { }, | |
teardown: function() { } | |
}); | |
test("works by itself", function() { | |
var count = 0; | |
repeat_until(function() { count+=1;return count; }, 0); | |
ok(count === 1, "no delay, so synchronous"); | |
}); | |
asyncTest("on pass and_then is called", function() { | |
var count = 0; | |
repeat_until(function() { | |
count+=1; | |
return count === 2 ? count : false; | |
}, 0).and_then(function(c) { | |
start(); | |
equal(count, c, "value passed through to and_then"); | |
}); | |
}); | |
asyncTest("on fail timeout is called", function() { | |
repeat_until(function() { | |
return false; | |
}, 0).and_then(function(c) { | |
start(); ok(false, "should not have gotten here"); | |
}).timeout(function(c) { | |
start(); ok(true, "failed as expected"); | |
}, 0); | |
}); | |
asyncTest("can be triggered immediately", function() { | |
repeat_until(function() { | |
return false; | |
}, 1000).and_then(function(c) { | |
start(); ok(true, "should not have gotten here"); | |
}).now(); | |
}); | |
test("and_then can be checked later", function() { | |
var x = repeat_until(function() { | |
return true; | |
}); | |
x.and_then(function(val) { | |
ok(val, "Successfully processed"); | |
}); | |
}); | |
asyncTest("timeout can be applied later", function() { | |
var x = repeat_until(function() { | |
return false; | |
}, 0); | |
x.timeout(function() { | |
start(); | |
ok(true, "Successfully applied timeout"); | |
}, 0); | |
}); | |
test("works in whatever order", function() { | |
repeat_until(function() { | |
return true; | |
}).timeout(function() { | |
ok(false, "should not have timed out"); | |
}).and_then(function(val) { | |
ok(val, "true returned from repeater"); | |
}); | |
}); | |
asyncTest("and_then, and_then, and_then", function() { | |
expect(3); | |
var count = 0; | |
var poll = repeat_until(function() { | |
if( ++count === 2) { | |
return "completed"; | |
} | |
return false; | |
}).and_then(function(val) { | |
equal("completed", val, "first callback done"); | |
}).and_then(function(val) { | |
start(); | |
equal("completed", val, "second callback done"); | |
poll.and_then(function(val) { | |
equal("completed", val, "fired immediately"); | |
}); | |
}); | |
}); | |
}()); | |
</script> | |
</head> | |
<body> | |
<p>Some content.</p> | |
<input type="hidden" id="mod_mgr_run_tests" value="true"/> | |
<h1 id="qunit-header">QUnit example</h1> | |
<h2 id="qunit-banner"></h2> | |
<div id="qunit-testrunner-toolbar"></div> | |
<h2 id="qunit-userAgent"></h2> | |
<ol id="qunit-tests"></ol> | |
<div id="qunit-fixture">test markup, will be hidden</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment