pax_global_header00006660000000000000000000000064130400133070014501gustar00rootroot0000000000000052 comment=4e4499cc60ac865f4bf8a83007c9bcf90c02abfa function-loop-1.0.1/000077500000000000000000000000001304001330700142745ustar00rootroot00000000000000function-loop-1.0.1/.gitignore000066400000000000000000000000311304001330700162560ustar00rootroot00000000000000.nyc_output node_modules function-loop-1.0.1/README.md000066400000000000000000000012631304001330700155550ustar00rootroot00000000000000# function-loop Run a list of functions in order in a given object context. The functions can be callback-taking or promise-returning. This module is [zalgo-exposing](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony), meaning that synchronous calls to the cb functions will result in a sync call to the supplied cb, and async calls will result in the cb being called asynchronously. It does not artificially defer if callbacks are called synchronously. ## API `loop(context, functionList, doneCallback, errorCallback)` Run all the functions in the context of the `context` object, and then call the `doneCallback` or call the `errorCallback` if there are any errors. function-loop-1.0.1/index.js000066400000000000000000000015111304001330700157370ustar00rootroot00000000000000module.exports = loop // this weird little engine is to loop if the cb's keep getting // called synchronously, since that's faster and makes shallower // stack traces, but recurse if any of them don't fire this tick function loop (self, arr, cb, onerr, i) { if (!i) i = 0 var running = false while (i < arr.length && !running) { running = true var sync = true try { var ret = arr[i].call(self, next) } catch (er) { return onerr.call(self,er) } if (ret && typeof ret.then === 'function') ret.then(next.bind(self, null), onerr.bind(self)) i++ sync = false } function next (er) { if (er) return onerr.call(self, er) else if (!sync) return loop(self, arr, cb, onerr, i) running = false } if (i >= arr.length && !running) return cb.call(self) } function-loop-1.0.1/package.json000066400000000000000000000012271304001330700165640ustar00rootroot00000000000000{ "name": "function-loop", "version": "1.0.1", "main": "index.js", "scripts": { "test": "tap test.js --100" }, "repository": { "type": "git", "url": "git+https://github.com/isaacs/function-loop.git" }, "keywords": [], "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "license": "ISC", "bugs": { "url": "https://github.com/isaacs/function-loop/issues" }, "homepage": "https://github.com/isaacs/function-loop#readme", "devDependencies": { "tap": "^9.0.3" }, "description": "Run a list of functions in order in a given object context. The functions can be callback-taking or promise-returning." } function-loop-1.0.1/test.js000066400000000000000000000044301304001330700156120ustar00rootroot00000000000000var t = require('tap') var loop = require('./') var obj = {} t.test('basic passing operation', function (t) { var i = 0 loop(obj, [ function (cb) { t.equal(this, obj, 'this is correct 1') t.equal(i, 0, '0') cb() i++ }, function () { t.equal(this, obj, 'this is correct 2') t.equal(i++, 1, '1') return Promise.resolve(true) }, function (cb) { t.equal(this, obj, 'this is correct 3') t.equal(i++, 2, '2') setTimeout(cb) }, function (cb) { t.equal(this, obj, 'this is correct 4') t.equal(i++, 3, '3') process.nextTick(cb) } ], function () { t.equal(this, obj, 'this is correct 5') t.equal(i++, 4, '4') t.end() }, function (er) { throw er }) t.equal(i, 2, '2, after loop() call') }) t.test('throws', function (t) { loop(obj, [ function (cb) { t.equal(this, obj, 'this is correct') throw new Error('foo') }, function () { t.fail('should not get here') } ], function () { t.fail('should not get here') }, function (er) { t.match(er, { message: 'foo' }) t.end() }) }) t.test('all sync', function (t) { var i = 0 loop(obj, [ function (cb) { t.equal(i++, 0); cb() }, function (cb) { t.equal(i++, 1); cb() }, function (cb) { t.equal(i++, 2); cb() }, function (cb) { t.equal(i++, 3); cb() }, function (cb) { t.equal(i++, 4); cb() } ], function () { t.equal(i++, 5) }, function (er) { throw er }) t.equal(i, 6) t.end() }) t.test('broken promise', function (t) { loop(obj, [ function (cb) { t.equal(this, obj, 'this is correct') return Promise.reject(new Error('foo')) }, function () { t.fail('should not get here') } ], function () { t.fail('should not get here') }, function (er) { t.equal(this, obj, 'this is correct') t.match(er, { message: 'foo' }) t.end() }) }) t.test('cb err', function (t) { loop(obj, [ function (cb) { t.equal(this, obj, 'this is correct') cb(new Error('foo')) }, function () { t.fail('should not get here') } ], function () { t.fail('should not get here') }, function (er) { t.equal(this, obj, 'this is correct') t.match(er, { message: 'foo' }) t.end() }) })