tastypie
Version:
Tastypie is a webservice API framework for Node.js based on Django's Tastypie Framework. It provides a convenient, yet powerful and highly customizable, abstraction for creating REST-style interfaces
115 lines (86 loc) • 2.89 kB
JavaScript
/*
defer
*/"use strict"
var kindOf = require("mout/lang/kindOf"),
now = require("mout/time/now"),
forEach = require("mout/array/forEach"),
indexOf = require("mout/array/indexOf")
var callbacks = {
timeout: {},
frame: [],
immediate: []
}
var push = function(collection, callback, context, defer){
var iterator = function(){
iterate(collection)
}
if (!collection.length) defer(iterator)
var entry = {
callback: callback,
context: context
}
collection.push(entry)
return function(){
var io = indexOf(collection, entry)
if (io > -1) collection.splice(io, 1)
}
}
var iterate = function(collection){
var time = now()
forEach(collection.splice(0), function(entry) {
entry.callback.call(entry.context, time)
})
}
var defer = function(callback, argument, context){
return (kindOf(argument) === "Number") ? defer.timeout(callback, argument, context) : defer.immediate(callback, argument)
}
if (global.process && process.nextTick){
defer.immediate = function(callback, context){
return push(callbacks.immediate, callback, context, process.nextTick)
}
} else if (global.setImmediate){
defer.immediate = function(callback, context){
return push(callbacks.immediate, callback, context, setImmediate)
}
} else if (global.postMessage && global.addEventListener){
addEventListener("message", function(event){
if (event.source === global && event.data === "@deferred"){
event.stopPropagation()
iterate(callbacks.immediate)
}
}, true)
defer.immediate = function(callback, context){
return push(callbacks.immediate, callback, context, function(){
postMessage("@deferred", "*")
})
}
} else {
defer.immediate = function(callback, context){
return push(callbacks.immediate, callback, context, function(iterator){
setTimeout(iterator, 0)
})
}
}
var requestAnimationFrame = global.requestAnimationFrame ||
global.webkitRequestAnimationFrame ||
global.mozRequestAnimationFrame ||
global.oRequestAnimationFrame ||
global.msRequestAnimationFrame ||
function(callback) {
setTimeout(callback, 1e3 / 60)
}
defer.frame = function(callback, context){
return push(callbacks.frame, callback, context, requestAnimationFrame)
}
var clear
defer.timeout = function(callback, ms, context){
var ct = callbacks.timeout
if (!clear) clear = defer.immediate(function(){
clear = null
callbacks.timeout = {}
})
return push(ct[ms] || (ct[ms] = []), callback, context, function(iterator){
setTimeout(iterator, ms)
})
}
module.exports = defer