This repository has been archived by the owner on Dec 21, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathdefer.js
114 lines (86 loc) · 2.71 KB
/
defer.js
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
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