1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- "use strict";
- var ensureNaturalNumber = require("type/natural-number/ensure")
- , ensurePlainFunction = require("type/plain-function/ensure")
- , ensure = require("type/ensure")
- , defineFunctionLength = require("../lib/private/define-function-length");
- module.exports = function (limit, callback) {
- limit = ensure(
- ["limit", limit, ensureNaturalNumber, { min: 1 }],
- ["callback", callback, ensurePlainFunction]
- )[0];
- var Promise = this, ongoingCount = 0, pending = [];
- var onSuccess, onFailure;
- var release = function () {
- --ongoingCount;
- if (ongoingCount >= limit) return;
- var next = pending.shift();
- if (!next) return;
- ++ongoingCount;
- try {
- next.resolve(
- Promise.resolve(callback.apply(next.context, next.arguments)).then(
- onSuccess, onFailure
- )
- );
- } catch (exception) {
- release();
- next.reject(exception);
- }
- };
- onSuccess = function (value) {
- release();
- return value;
- };
- onFailure = function (exception) {
- release();
- throw exception;
- };
- return defineFunctionLength(callback.length, function () {
- if (ongoingCount >= limit) {
- var context = this, args = arguments;
- return new Promise(function (resolve, reject) {
- pending.push({
- context: context,
- arguments: args,
- resolve: resolve,
- reject: reject
- });
- });
- }
- ++ongoingCount;
- try {
- return Promise.resolve(callback.apply(this, arguments)).then(onSuccess, onFailure);
- } catch (exception) { return onFailure(exception); }
- });
- };
|