Skip to content

Instantly share code, notes, and snippets.

@wheeyls
Created December 6, 2011 03:47
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 wheeyls/1436623 to your computer and use it in GitHub Desktop.
Save wheeyls/1436623 to your computer and use it in GitHub Desktop.
Repeat until - a simple polling function
/**
* 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));
<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