|
|
- 'use strict';
-
- // This file contains then/promise specific extensions that are only useful
- // for node.js interop
-
- var Promise = require('./core.js');
- var asap = require('asap');
-
- module.exports = Promise;
-
- /* Static Functions */
-
- Promise.denodeify = function (fn, argumentCount) {
- if (
- typeof argumentCount === 'number' && argumentCount !== Infinity
- ) {
- return denodeifyWithCount(fn, argumentCount);
- } else {
- return denodeifyWithoutCount(fn);
- }
- };
-
- var callbackFn = (
- 'function (err, res) {' +
- 'if (err) { rj(err); } else { rs(res); }' +
- '}'
- );
- function denodeifyWithCount(fn, argumentCount) {
- var args = [];
- for (var i = 0; i < argumentCount; i++) {
- args.push('a' + i);
- }
- var body = [
- 'return function (' + args.join(',') + ') {',
- 'var self = this;',
- 'return new Promise(function (rs, rj) {',
- 'var res = fn.call(',
- ['self'].concat(args).concat([callbackFn]).join(','),
- ');',
- 'if (res &&',
- '(typeof res === "object" || typeof res === "function") &&',
- 'typeof res.then === "function"',
- ') {rs(res);}',
- '});',
- '};'
- ].join('');
- return Function(['Promise', 'fn'], body)(Promise, fn);
- }
- function denodeifyWithoutCount(fn) {
- var fnLength = Math.max(fn.length - 1, 3);
- var args = [];
- for (var i = 0; i < fnLength; i++) {
- args.push('a' + i);
- }
- var body = [
- 'return function (' + args.join(',') + ') {',
- 'var self = this;',
- 'var args;',
- 'var argLength = arguments.length;',
- 'if (arguments.length > ' + fnLength + ') {',
- 'args = new Array(arguments.length + 1);',
- 'for (var i = 0; i < arguments.length; i++) {',
- 'args[i] = arguments[i];',
- '}',
- '}',
- 'return new Promise(function (rs, rj) {',
- 'var cb = ' + callbackFn + ';',
- 'var res;',
- 'switch (argLength) {',
- args.concat(['extra']).map(function (_, index) {
- return (
- 'case ' + (index) + ':' +
- 'res = fn.call(' + ['self'].concat(args.slice(0, index)).concat('cb').join(',') + ');' +
- 'break;'
- );
- }).join(''),
- 'default:',
- 'args[argLength] = cb;',
- 'res = fn.apply(self, args);',
- '}',
-
- 'if (res &&',
- '(typeof res === "object" || typeof res === "function") &&',
- 'typeof res.then === "function"',
- ') {rs(res);}',
- '});',
- '};'
- ].join('');
-
- return Function(
- ['Promise', 'fn'],
- body
- )(Promise, fn);
- }
-
- Promise.nodeify = function (fn) {
- return function () {
- var args = Array.prototype.slice.call(arguments);
- var callback =
- typeof args[args.length - 1] === 'function' ? args.pop() : null;
- var ctx = this;
- try {
- return fn.apply(this, arguments).nodeify(callback, ctx);
- } catch (ex) {
- if (callback === null || typeof callback == 'undefined') {
- return new Promise(function (resolve, reject) {
- reject(ex);
- });
- } else {
- asap(function () {
- callback.call(ctx, ex);
- })
- }
- }
- }
- };
-
- Promise.prototype.nodeify = function (callback, ctx) {
- if (typeof callback != 'function') return this;
-
- this.then(function (value) {
- asap(function () {
- callback.call(ctx, null, value);
- });
- }, function (err) {
- asap(function () {
- callback.call(ctx, err);
- });
- });
- };
|