From ac46df8daea09899ce30dc8fd70986e258c746bf Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 9 Feb 2018 06:46:43 -0500 Subject: Move Add-on SDK source to toolkit/jetpack --- toolkit/jetpack/sdk/lang/functional/concurrent.js | 110 ++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 toolkit/jetpack/sdk/lang/functional/concurrent.js (limited to 'toolkit/jetpack/sdk/lang/functional/concurrent.js') diff --git a/toolkit/jetpack/sdk/lang/functional/concurrent.js b/toolkit/jetpack/sdk/lang/functional/concurrent.js new file mode 100644 index 000000000..85e8cff46 --- /dev/null +++ b/toolkit/jetpack/sdk/lang/functional/concurrent.js @@ -0,0 +1,110 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Disclaimer: Some of the functions in this module implement APIs from +// Jeremy Ashkenas's http://underscorejs.org/ library and all credits for +// those goes to him. + +"use strict"; + +module.metadata = { + "stability": "unstable" +}; + +const { arity, name, derive, invoke } = require("./helpers"); +const { setTimeout, clearTimeout, setImmediate } = require("../../timers"); + +/** + * Takes a function and returns a wrapped one instead, calling which will call + * original function in the next turn of event loop. This is basically utility + * to do `setImmediate(function() { ... })`, with a difference that returned + * function is reused, instead of creating a new one each time. This also allows + * to use this functions as event listeners. + */ +const defer = f => derive(function(...args) { + setImmediate(invoke, f, args, this); +}, f); +exports.defer = defer; +// Exporting `remit` alias as `defer` may conflict with promises. +exports.remit = defer; + +/** + * Much like setTimeout, invokes function after wait milliseconds. If you pass + * the optional arguments, they will be forwarded on to the function when it is + * invoked. + */ +const delay = function delay(f, ms, ...args) { + setTimeout(() => f.apply(this, args), ms); +}; +exports.delay = delay; + +/** + * From underscore's `_.debounce` + * http://underscorejs.org + * (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Underscore may be freely distributed under the MIT license. + */ +const debounce = function debounce (fn, wait) { + let timeout, args, context, timestamp, result; + + let later = function () { + let last = Date.now() - timestamp; + if (last < wait) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + result = fn.apply(context, args); + context = args = null; + } + }; + + return function (...aArgs) { + context = this; + args = aArgs; + timestamp = Date.now(); + if (!timeout) { + timeout = setTimeout(later, wait); + } + + return result; + }; +}; +exports.debounce = debounce; + +/** + * From underscore's `_.throttle` + * http://underscorejs.org + * (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Underscore may be freely distributed under the MIT license. + */ +const throttle = function throttle (func, wait, options) { + let context, args, result; + let timeout = null; + let previous = 0; + options || (options = {}); + let later = function() { + previous = options.leading === false ? 0 : Date.now(); + timeout = null; + result = func.apply(context, args); + context = args = null; + }; + return function() { + let now = Date.now(); + if (!previous && options.leading === false) previous = now; + let remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0) { + clearTimeout(timeout); + timeout = null; + previous = now; + result = func.apply(context, args); + context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; +}; +exports.throttle = throttle; -- cgit v1.2.3