Bearsampp / sandbox

R&D Repo for Bearsampp
GNU General Public License v3.0
0 stars 1 forks source link

Simplify once partialing has been removed #77

Closed github-actions[bot] closed 3 months ago

github-actions[bot] commented 3 months ago

https://github.com/Bearsampp/sandbox/blob/cc052526131630b0528e9a081926498074d9d1a9/core/libs/nodejs/node_modules/when/node.js#L143


/** @license MIT License (c) copyright 2013 original author or authors */

/**
 * Collection of helpers for interfacing with node-style asynchronous functions
 * using promises.
 *
 * @author Brian Cavalier
 * @contributor Renato Zannon
 */

(function(define) {
define(function(require) {

    var when = require('./when');
    var _liftAll = require('./lib/liftAll');
    var setTimer = require('./lib/env').setTimer;
    var slice = Array.prototype.slice;

    var _apply = require('./lib/apply')(when.Promise, dispatch);

    return {
        lift: lift,
        liftAll: liftAll,
        apply: apply,
        call: call,
        createCallback: createCallback,
        bindCallback: bindCallback,
        liftCallback: liftCallback
    };

    /**
     * Takes a node-style async function and calls it immediately (with an optional
     * array of arguments or promises for arguments). It returns a promise whose
     * resolution depends on whether the async functions calls its callback with the
     * conventional error argument or not.
     *
     * With this it becomes possible to leverage existing APIs while still reaping
     * the benefits of promises.
     *
     * @example
     *    function onlySmallNumbers(n, callback) {
     *      if(n < 10) {
     *          callback(null, n + 10);
     *      } else {
     *          callback(new Error("Calculation failed"));
     *      }
     *  }
     *
     *    var nodefn = require("when/node/function");
     *
     *    // Logs '15'
     *    nodefn.apply(onlySmallNumbers, [5]).then(console.log, console.error);
     *
     *    // Logs 'Calculation failed'
     *    nodefn.apply(onlySmallNumbers, [15]).then(console.log, console.error);
     *
     * @param {function} f node-style function that will be called
     * @param {Array} [args] array of arguments to func
     * @returns {Promise} promise for the value func passes to its callback
     */
    function apply(f, args) {
        return _apply(f, this, args || []);
    }

    function dispatch(f, thisArg, args, h) {
        var cb = createCallback(h);
        try {
            switch(args.length) {
                case 2: f.call(thisArg, args[0], args[1], cb); break;
                case 1: f.call(thisArg, args[0], cb); break;
                case 0: f.call(thisArg, cb); break;
                default:
                    args.push(cb);
                    f.apply(thisArg, args);
            }
        } catch(e) {
            h.reject(e);
        }
    }

    /**
     * Has the same behavior that {@link apply} has, with the difference that the
     * arguments to the function are provided individually, while {@link apply} accepts
     * a single array.
     *
     * @example
     *    function sumSmallNumbers(x, y, callback) {
     *      var result = x + y;
     *      if(result < 10) {
     *          callback(null, result);
     *      } else {
     *          callback(new Error("Calculation failed"));
     *      }
     *  }
     *
     *    // Logs '5'
     *    nodefn.call(sumSmallNumbers, 2, 3).then(console.log, console.error);
     *
     *    // Logs 'Calculation failed'
     *    nodefn.call(sumSmallNumbers, 5, 10).then(console.log, console.error);
     *
     * @param {function} f node-style function that will be called
     * @param {...*} [args] arguments that will be forwarded to the function
     * @returns {Promise} promise for the value func passes to its callback
     */
    function call(f /*, args... */) {
        return _apply(f, this, slice.call(arguments, 1));
    }

    /**
     * Takes a node-style function and returns new function that wraps the
     * original and, instead of taking a callback, returns a promise. Also, it
     * knows how to handle promises given as arguments, waiting for their
     * resolution before executing.
     *
     * Upon execution, the orginal function is executed as well. If it passes
     * a truthy value as the first argument to the callback, it will be
     * interpreted as an error condition, and the promise will be rejected
     * with it. Otherwise, the call is considered a resolution, and the promise
     * is resolved with the callback's second argument.
     *
     * @example
     *    var fs = require("fs"), nodefn = require("when/node/function");
     *
     *    var promiseRead = nodefn.lift(fs.readFile);
     *
     *    // The promise is resolved with the contents of the file if everything
     *    // goes ok
     *    promiseRead('exists.txt').then(console.log, console.error);
     *
     *    // And will be rejected if something doesn't work out
     *    // (e.g. the files does not exist)
     *    promiseRead('doesnt_exist.txt').then(console.log, console.error);
     *
     *
     * @param {Function} f node-style function to be lifted
     * @param {...*} [args] arguments to be prepended for the new function @deprecated
     * @returns {Function} a promise-returning function
     */
    function lift(f /*, args... */) {
        var args1 = arguments.length > 1 ? slice.call(arguments, 1) : [];
        return function() {
            // TODO: Simplify once partialing has been removed
            var l = args1.length;
            var al = arguments.length;
            var args = new Array(al + l);
            var i;
            for(i=0; i<l; ++i) {
                args[i] = args1[i];
            }
            for(i=0; i<al; ++i) {
                args[i+l] = arguments[i];
            }
            return _apply(f, this, args);
        };
    }

    /**
     * Lift all the functions/methods on src
     * @param {object|function} src source whose functions will be lifted
     * @param {function?} combine optional function for customizing the lifting
     *  process. It is passed dst, the lifted function, and the property name of
     *  the original function on src.
     * @param {(object|function)?} dst option destination host onto which to place lifted
     *  functions. If not provided, liftAll returns a new object.
     * @returns {*} If dst is provided, returns dst with lifted functions as
     *  properties.  If dst not provided, returns a new object with lifted functions.
     */
    function liftAll(src, combine, dst) {
        return _liftAll(lift, combine, dst, src);
    }

    /**
     * Takes an object that responds to the resolver interface, and returns
     * a function that will resolve or reject it depending on how it is called.
     *
     * @example
     *  function callbackTakingFunction(callback) {
     *      if(somethingWrongHappened) {
     *          callback(error);
     *      } else {
     *          callback(null, interestingValue);
     *      }
     *  }
     *
     *  var when = require('when'), nodefn = require('when/node/function');
     *
     *  var deferred = when.defer();
     *  callbackTakingFunction(nodefn.createCallback(deferred.resolver));
     *
     *  deferred.promise.then(function(interestingValue) {
     *      // Use interestingValue
     *  });
     *
     * @param {Resolver} resolver that will be 'attached' to the callback
     * @returns {Function} a node-style callback function
     */
    function createCallback(resolver) {
        return function(err, value) {
            if(err) {
                resolver.reject(err);
            } else if(arguments.length > 2) {
                resolver.resolve(slice.call(arguments, 1));
            } else {
                resolver.resolve(value);
            }
        };
    }

    /**
     * Attaches a node-style callback to a promise, ensuring the callback is
     * called for either fulfillment or rejection. Returns a promise with the same
     * state as the passed-in promise.
     *
     * @example
     *  var deferred = when.defer();
     *
     *  function callback(err, value) {
     *      // Handle err or use value
     *  }
     *
     *  bindCallback(deferred.promise, callback);
     *
     *  deferred.resolve('interesting value');
     *
     * @param {Promise} promise The promise to be attached to.
     * @param {Function} callback The node-style callback to attach.
     * @returns {Promise} A promise with the same state as the passed-in promise.
     */
    function bindCallback(promise, callback) {
        promise = when(promise);

        if (callback) {
            promise.then(success, wrapped);
        }

        return promise;

        function success(value) {
            wrapped(null, value);
        }

        function wrapped(err, value) {
            setTimer(function () {
                callback(err, value);
            }, 0);
        }
    }

    /**
     * Takes a node-style callback and returns new function that accepts a
     * promise, calling the original callback when the promise is either
     * fulfilled or rejected with the appropriate arguments.
     *
     * @example
     *  var deferred = when.defer();
     *
     *  function callback(err, value) {
     *      // Handle err or use value
     *  }
     *
     *  var wrapped = liftCallback(callback);
     *
     *  // `wrapped` can now be passed around at will
     *  wrapped(deferred.promise);
     *
     *  deferred.resolve('interesting value');
     *
     * @param {Function} callback The node-style callback to wrap.
     * @returns {Function} The lifted, promise-accepting function.
     */
    function liftCallback(callback) {
        return function(promise) {
            return bindCallback(promise, callback);
        };
    }
});

})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
github-actions[bot] commented 3 months ago

Closed in 0fc4b259dec266089dfe33817361dad75536acf8

github-actions[bot] commented 3 months ago

Closed in 0fc4b259dec266089dfe33817361dad75536acf8

github-actions[bot] commented 3 months ago

Closed in 0fc4b259dec266089dfe33817361dad75536acf8