public
Created

soon

  • Download Gist
soon.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
YUI.add('soon', function (Y) {
/**
* Provides a setImmediate/process.nextTick/setTimeout wrapper.
* @module soon
* @author Steven Olmsted
*/
 
var global = Y.config.global,
 
/**
* Y.soon accepts a callback function. The callback function will be called
* once in a future turn of the JavaScript event loop. If the function
* requires a specific execution context or arguments, wrap it with Y.bind.
* Y.soon returns an object with a cancel method. If the cancel method is
* called before the callback function, the callback function won't be
* called.
* @method soon
* @for YUI
* @param {Function} callbackFunction
* @return {Object} An object with a cancel method. If the cancel method is
* called before the callback function, the callback function won't be
* called.
*/
soon = function (callbackFunction) {
var canceled;
 
soon._asynchronizer(function () {
// Some asynchronizers may provide their own cancellation
// methods such as clearImmediate or clearTimeout but some
// asynchronizers do not. For simplicity, cancellation is
// entirely handled here rather than wrapping the other methods.
// All asynchronizers are expected to always call this anonymous
// function.
if (!canceled) {
callbackFunction();
}
});
 
return {
cancel: function () {
canceled = 1;
}
};
};
 
/**
* The asynchronizer is the internal mechanism which will call a function
* asynchronously. This property is exposed as a convenient way to define a
* different asynchronizer implementation without having to rewrite the
* entire Y.soon interface.
* @method _asynchronizer
* @for soon
* @param {Function} callbackFunction The function to call asynchronously.
* @protected
*/
 
/**
* Since Y.soon is likely to have many differing asynchronizer
* implementations, this property should be set to identify which
* implementation is in use.
* @property _impl
* @protected
* @type String
*/
 
// Check for a native or already polyfilled implementation of setImmediate.
if ('setImmediate' in global) {
soon._asynchronizer = function (callbackFunction) {
setImmediate(callbackFunction);
};
soon._impl = 'setImmediate';
}
 
// Check for process and process.nextTick
else if (('process' in global) && ('nextTick' in process)) {
soon._asynchronizer = process.nextTick;
soon._impl = 'nextTick';
}
 
// The most widely supported asynchronizer is setTimeout so we use that as
// the fallback.
else {
soon._asynchronizer = function (callbackFunction) {
setTimeout(callbackFunction, 0);
};
soon._impl = 'setTimeout';
}
 
Y.soon = soon;
}, '', {
requires: [
'yui-base'
]
});

You may want to change soon = function () { to function soon() {.

Why are you exposing the method in _impl?

_asynchronizer and _impl are here so other implementations can be used conditionally. In environments that don't support setImmediate there are other alternatives that are possibly better than setTimeout. There needs to be a way to determine which implementation is in use before you change it.

I personally avoid named functions in my code. After a quick browse through YUI's source, I see both styles used. There doesn't seem to be a preference.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.