You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.7 KiB
90 lines
2.7 KiB
/* eslint consistent-this: 0 */ |
|
|
|
// Timeout cached values |
|
|
|
"use strict"; |
|
|
|
var aFrom = require("es5-ext/array/from") |
|
, forEach = require("es5-ext/object/for-each") |
|
, nextTick = require("next-tick") |
|
, isPromise = require("is-promise") |
|
, timeout = require("timers-ext/valid-timeout") |
|
, extensions = require("../lib/registered-extensions"); |
|
|
|
var noop = Function.prototype, max = Math.max, min = Math.min, create = Object.create; |
|
|
|
extensions.maxAge = function (maxAge, conf, options) { |
|
var timeouts, postfix, preFetchAge, preFetchTimeouts; |
|
|
|
maxAge = timeout(maxAge); |
|
if (!maxAge) return; |
|
|
|
timeouts = create(null); |
|
postfix = |
|
(options.async && extensions.async) || (options.promise && extensions.promise) |
|
? "async" |
|
: ""; |
|
conf.on("set" + postfix, function (id) { |
|
timeouts[id] = setTimeout(function () { conf.delete(id); }, maxAge); |
|
if (typeof timeouts[id].unref === "function") timeouts[id].unref(); |
|
if (!preFetchTimeouts) return; |
|
if (preFetchTimeouts[id]) { |
|
if (preFetchTimeouts[id] !== "nextTick") clearTimeout(preFetchTimeouts[id]); |
|
} |
|
preFetchTimeouts[id] = setTimeout(function () { |
|
delete preFetchTimeouts[id]; |
|
}, preFetchAge); |
|
if (typeof preFetchTimeouts[id].unref === "function") preFetchTimeouts[id].unref(); |
|
}); |
|
conf.on("delete" + postfix, function (id) { |
|
clearTimeout(timeouts[id]); |
|
delete timeouts[id]; |
|
if (!preFetchTimeouts) return; |
|
if (preFetchTimeouts[id] !== "nextTick") clearTimeout(preFetchTimeouts[id]); |
|
delete preFetchTimeouts[id]; |
|
}); |
|
|
|
if (options.preFetch) { |
|
if (options.preFetch === true || isNaN(options.preFetch)) { |
|
preFetchAge = 0.333; |
|
} else { |
|
preFetchAge = max(min(Number(options.preFetch), 1), 0); |
|
} |
|
if (preFetchAge) { |
|
preFetchTimeouts = {}; |
|
preFetchAge = (1 - preFetchAge) * maxAge; |
|
conf.on("get" + postfix, function (id, args, context) { |
|
if (!preFetchTimeouts[id]) { |
|
preFetchTimeouts[id] = "nextTick"; |
|
nextTick(function () { |
|
var result; |
|
if (preFetchTimeouts[id] !== "nextTick") return; |
|
delete preFetchTimeouts[id]; |
|
conf.delete(id); |
|
if (options.async) { |
|
args = aFrom(args); |
|
args.push(noop); |
|
} |
|
result = conf.memoized.apply(context, args); |
|
if (options.promise) { |
|
// Supress eventual error warnings |
|
if (isPromise(result)) { |
|
if (typeof result.done === "function") result.done(noop, noop); |
|
else result.then(noop, noop); |
|
} |
|
} |
|
}); |
|
} |
|
}); |
|
} |
|
} |
|
|
|
conf.on("clear" + postfix, function () { |
|
forEach(timeouts, function (id) { clearTimeout(id); }); |
|
timeouts = {}; |
|
if (preFetchTimeouts) { |
|
forEach(preFetchTimeouts, function (id) { if (id !== "nextTick") clearTimeout(id); }); |
|
preFetchTimeouts = {}; |
|
} |
|
}); |
|
};
|
|
|