async-future
Advanced tools
Comparing version 1.0.3 to 1.0.4
@@ -19,3 +19,3 @@ /* Copyright (c) 2013 Billy Tetrud - Free to use for any purpose: MIT License*/ | ||
this.queue = [] | ||
this.n = 0 // future depth (for preventing "too much recursion" RangeErrors) | ||
this.n = 1 // future depth (for preventing "too much recursion" RangeErrors) | ||
if(Future.debug) { | ||
@@ -124,5 +124,2 @@ curId++ | ||
function setNext(that, future) { | ||
if(future !== undefined && !isLikeAFuture(future) ) | ||
throw Error("Value returned from then or catch *not* a Future: "+future) | ||
resolve(that, 'next', future) | ||
@@ -152,3 +149,3 @@ } | ||
try { | ||
setNext(f, cb(this.result)) | ||
setNext(f, executeCallback(cb,this.result)) | ||
} catch(e) { | ||
@@ -173,3 +170,3 @@ f.throw(e) | ||
try { | ||
setNext(f, cb(this.result)) | ||
setNext(f, executeCallback(cb,this.result)) | ||
} catch(e) { | ||
@@ -189,3 +186,3 @@ f.throw(e) | ||
try { | ||
setNext(f, cb(this.error)) | ||
setNext(f, executeCallback(cb,this.error)) | ||
} catch(e) { | ||
@@ -199,3 +196,3 @@ f.throw(e) | ||
try { | ||
setNext(f, cb(e)) | ||
setNext(f, executeCallback(cb,e)) | ||
} catch(e) { | ||
@@ -220,7 +217,7 @@ f.throw(e) | ||
this.next.then(function(v) { | ||
var x = cb() | ||
var x = executeCallback(cb) | ||
f.return(v) | ||
return x | ||
}).catch(function(e) { | ||
var x = cb() | ||
var x = executeCallback(cb) | ||
f.throw(e) | ||
@@ -231,3 +228,3 @@ return x | ||
Future(true).then(function() { | ||
return cb() | ||
return executeCallback(cb) | ||
}).then(function() { | ||
@@ -241,3 +238,3 @@ f.throw(that.error) | ||
Future(true).then(function() { | ||
return cb() | ||
return executeCallback(cb) | ||
}).then(function() { | ||
@@ -338,2 +335,11 @@ f.return(that.result) | ||
// executes a callback and ensures that it returns a future | ||
function executeCallback(cb, arg) { | ||
var r = cb(arg) | ||
if(r !== undefined && !isLikeAFuture(r) ) | ||
throw Error("Value returned from then or catch ("+r+") is *not* a Future. Callback: "+cb.toString()) | ||
return r | ||
} | ||
function createException() { | ||
@@ -340,0 +346,0 @@ try { |
@@ -20,3 +20,3 @@ !function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.asyncFuture=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ | ||
this.queue = [] | ||
this.n = 0 // future depth (for preventing "too much recursion" RangeErrors) | ||
this.n = 1 // future depth (for preventing "too much recursion" RangeErrors) | ||
if(Future.debug) { | ||
@@ -118,2 +118,5 @@ curId++ | ||
Future.prototype.throw = function(e) { | ||
if(this.location !== undefined) { | ||
e.stack += '\n ---------------------------\n'+this.location.stack.split('\n').slice(4).join('\n') | ||
} | ||
resolve(this, 'error', e) | ||
@@ -123,5 +126,2 @@ } | ||
function setNext(that, future) { | ||
if(future !== undefined && !isLikeAFuture(future) ) | ||
throw Error("Value returned from then or catch *not* a Future: "+future) | ||
resolve(that, 'next', future) | ||
@@ -151,3 +151,3 @@ } | ||
try { | ||
setNext(f, cb(this.result)) | ||
setNext(f, executeCallback(cb,this.result)) | ||
} catch(e) { | ||
@@ -164,4 +164,3 @@ f.throw(e) | ||
Future.prototype.then = function(cb) { | ||
var f = new Future | ||
f.n = this.n + 1 | ||
var f = createChainFuture(this) | ||
wait(this, function() { | ||
@@ -174,3 +173,3 @@ if(this.hasError) | ||
try { | ||
setNext(f, cb(this.result)) | ||
setNext(f, executeCallback(cb,this.result)) | ||
} catch(e) { | ||
@@ -186,8 +185,7 @@ f.throw(e) | ||
Future.prototype.catch = function(cb) { | ||
var f = new Future | ||
f.n = this.n + 1 | ||
var f = createChainFuture(this) | ||
wait(this, function() { | ||
if(this.hasError) { | ||
try { | ||
setNext(f, cb(this.error)) | ||
setNext(f, executeCallback(cb,this.error)) | ||
} catch(e) { | ||
@@ -201,3 +199,3 @@ f.throw(e) | ||
try { | ||
setNext(f, cb(e)) | ||
setNext(f, executeCallback(cb,e)) | ||
} catch(e) { | ||
@@ -216,4 +214,3 @@ f.throw(e) | ||
Future.prototype.finally = function(cb) { | ||
var f = new Future | ||
f.n = this.n + 1 | ||
var f = createChainFuture(this) | ||
wait(this, function() { | ||
@@ -224,7 +221,7 @@ try { | ||
this.next.then(function(v) { | ||
var x = cb() | ||
var x = executeCallback(cb) | ||
f.return(v) | ||
return x | ||
}).catch(function(e) { | ||
var x = cb() | ||
var x = executeCallback(cb) | ||
f.throw(e) | ||
@@ -235,3 +232,3 @@ return x | ||
Future(true).then(function() { | ||
return cb() | ||
return executeCallback(cb) | ||
}).then(function() { | ||
@@ -245,3 +242,3 @@ f.throw(that.error) | ||
Future(true).then(function() { | ||
return cb() | ||
return executeCallback(cb) | ||
}).then(function() { | ||
@@ -260,2 +257,12 @@ f.return(that.result) | ||
// a future created for the chain functions (then, catch, and finally) | ||
function createChainFuture(that) { | ||
var f = new Future | ||
f.n = that.n + 1 | ||
if(Future.debug) { | ||
f.location = createException() // used for long traces | ||
} | ||
return f | ||
} | ||
// all unused futures should end with this (e.g. most then-chains) | ||
@@ -309,3 +316,6 @@ // detatches the future so any propogated exception is thrown (so the exception isn't silently lost) | ||
if(that.n % 500 !== 0) { | ||
// 100 is a pretty arbitrary number - it should be set significantly lower than common maximum stack depths, and high enough to make sure performance isn't significantly affected | ||
// in using this for deadunit, firefox was getting a recursion error at 150, but not at 100. This doesn't mean that it can't happen at 100 too, but it'll certainly make it less likely | ||
// if you're getting recursion errors even with this mechanism, you probably need to figure that out in your own code | ||
if(that.n % 100 !== 0) { | ||
executeCallbacks(that, that.queue) | ||
@@ -330,2 +340,19 @@ } else { | ||
} | ||
// executes a callback and ensures that it returns a future | ||
function executeCallback(cb, arg) { | ||
var r = cb(arg) | ||
if(r !== undefined && !isLikeAFuture(r) ) | ||
throw Error("Value returned from then or catch ("+r+") is *not* a Future. Callback: "+cb.toString()) | ||
return r | ||
} | ||
function createException() { | ||
try { | ||
throw new Error() | ||
} catch(e) { | ||
return e | ||
} | ||
} | ||
},{"trimArguments":2}],2:[function(_dereq_,module,exports){ | ||
@@ -332,0 +359,0 @@ // resolves varargs variable into more usable form |
{"name":"async-future", | ||
"description": "A powerful and yet simple futures library for javascript in node.js and in-browser.", | ||
"keywords": ["future", "promise", "deferred", "async", "parallel", "thread", "concurrency"], | ||
"version":"1.0.3", | ||
"version":"1.0.4", | ||
"main": "asyncFuture.js", | ||
@@ -6,0 +6,0 @@ "author": "Billy Tetrud <bitetrudpublic@gmail.com> (https://github.com/fresheneesz/)", |
@@ -191,2 +191,6 @@ `async-future` | ||
* 1.0.4 | ||
* changing a future's initial 'n' so that a setTimeout doesn't happen for the first few hundred chains | ||
* adding some info to "callback returned an object that isn't a future" error | ||
* fixing browser tests (they need testServer.js to be running) | ||
* 1.0.3 - adding long traces (when Future.debug is set to true) | ||
@@ -193,0 +197,0 @@ * 1.0.2 - adding code to prevent "too much recursion" RangeErrors from being caused by code with a ridiculous number of chained `then`s using a setTimeout every 400th chain |
@@ -6,4 +6,85 @@ "use strict"; | ||
var test = Unit.test("Testing async futures", tests).writeConsole() | ||
var test = Unit.test("Testing async futures", function(t) { | ||
var afterSharedTests | ||
this.test('shared tests', function(t) { | ||
afterSharedTests = tests.call(this, t, 'node') | ||
}) | ||
afterSharedTests.then(function() { | ||
t.test('node-specific tests', function(t) { | ||
var Future = require('../asyncFuture') | ||
t.test("done should cause an asynchronous error (by default)", function(t) { | ||
this.count(1) | ||
var d = require('domain').create(); | ||
d.on('error', function(er) { | ||
t.ok(er === 'something',er) | ||
}) | ||
d.run(function() { | ||
Future(true).then(function(){ | ||
throw "something" | ||
}).done() | ||
}) | ||
}) | ||
t.test('former bugs', function(t) { | ||
this.test("exception in returned future", function(t) { | ||
this.count(1) | ||
var d = require('domain').create() | ||
d.on('error', function(err) { | ||
t.ok(err.message === "Inner Exception1", err.message) | ||
}) | ||
d.run(function() { | ||
Future(true).then(function() { | ||
var f = new Future | ||
f.throw(Error("Inner Exception1")) | ||
return f | ||
}).done() | ||
}) | ||
}) | ||
this.test("exception in returned future, passed through a finally", function(t) { | ||
this.count(2) | ||
var d = require('domain').create() | ||
d.on('error', function(err) { | ||
t.ok(err.message === "Inner Exception2", err.message) | ||
}) | ||
d.run(function() { | ||
Future(true).then(function() { | ||
var f = new Future | ||
f.throw(Error("Inner Exception2")) | ||
return f | ||
}).finally(function() { | ||
// do nothing | ||
t.ok(true) | ||
}).done() | ||
}) | ||
}) | ||
this.test("exception in future returned from a finally", function(t) { | ||
this.count(1) | ||
var d = require('domain').create() | ||
d.on('error', function(err) { | ||
t.ok(true) | ||
}) | ||
d.run(function() { | ||
Future(true).finally(function() { | ||
var innerf = new Future | ||
innerf.throw("test") | ||
return innerf | ||
}).done() | ||
}) | ||
}) | ||
}) | ||
}) | ||
}).done() | ||
}).writeConsole() | ||
var Future = require('../asyncFuture') | ||
// type can be either "browser" or "node" | ||
module.exports = function(t, type) { | ||
module.exports = function(t) { | ||
//* | ||
this.count(12) | ||
this.count(11) | ||
@@ -42,3 +41,3 @@ var futures = [] | ||
t.test("exceptions", function(t) { | ||
this.count(9) | ||
this.count(8) | ||
@@ -126,15 +125,2 @@ f3 = new Future() | ||
t.test("done should cause an asynchronous error (by default)", function(t) { | ||
this.count(1) | ||
var d = require('domain').create(); | ||
d.on('error', function(er) { | ||
t.ok(er === 'something',er) | ||
}) | ||
d.run(function() { | ||
Future(true).then(function(){ | ||
throw "something" | ||
}).done() | ||
}) | ||
}) | ||
exceptionTestsDone.return() | ||
@@ -145,18 +131,4 @@ }) | ||
exceptionTestsDone.then(function() { | ||
var futures = [] | ||
return exceptionTestsDone.then(function() { | ||
t.test("done should cause an asynchronous error (by default)", function(t) { | ||
this.count(1) | ||
var d = require('domain').create(); | ||
d.on('error', function(er) { | ||
t.ok(er === 'something',er) | ||
}) | ||
d.run(function() { | ||
Future(true).then(function(){ | ||
throw "something" | ||
}).done() | ||
}) | ||
}) | ||
t.test("chaining", function(t) { | ||
@@ -300,7 +272,10 @@ this.count(3) | ||
var lineNumber = '311' | ||
if(type === 'node') | ||
var lineNumber = '286' | ||
else | ||
var lineNumber = '8952' | ||
Future.debug=false // make sure long traces don't happen when debug is false | ||
test(function(t, e) { | ||
t.ok(e.stack.toString().indexOf(lineNumber) === -1) | ||
t.ok(e.stack.toString().indexOf(lineNumber) === -1, e.stack) | ||
}) | ||
@@ -310,3 +285,3 @@ | ||
test(function(t, e) { | ||
t.ok(e.stack.toString().indexOf(lineNumber) !== -1) | ||
t.ok(e.stack.toString().indexOf(lineNumber) !== -1, e.stack) | ||
}) | ||
@@ -331,3 +306,3 @@ | ||
t.test("former bugs", function() { | ||
this.count(10) | ||
this.count(7) | ||
@@ -350,68 +325,2 @@ this.test("Return result of then", function(t) { | ||
this.test("exception in returned future", function(t) { | ||
this.count(1) | ||
var f = new Future | ||
futures.push(f) | ||
var d = require('domain').create() | ||
d.on('error', function(err) { | ||
t.ok(err.message === "Inner Exception1", err.message) | ||
f.return() | ||
}) | ||
d.run(function() { | ||
Future(true).then(function() { | ||
var f = new Future | ||
f.throw(Error("Inner Exception1")) | ||
return f | ||
}).done() | ||
}) | ||
}) | ||
this.test("exception in returned future, passed through a finally", function(t) { | ||
this.count(2) | ||
var f = new Future | ||
futures.push(f) | ||
var d = require('domain').create() | ||
d.on('error', function(err) { | ||
t.ok(err.message === "Inner Exception2", err.message) | ||
f.return() | ||
}) | ||
d.run(function() { | ||
Future(true).then(function() { | ||
var f = new Future | ||
f.throw(Error("Inner Exception2")) | ||
return f | ||
}).finally(function() { | ||
// do nothing | ||
t.ok(true) | ||
}).done() | ||
}) | ||
}) | ||
this.test("exception in future returned from a finally", function(t) { | ||
this.count(1) | ||
var f = new Future | ||
futures.push(f) | ||
var d = require('domain').create() | ||
d.on('error', function(err) { | ||
t.ok(true) | ||
}) | ||
d.run(function() { | ||
Future(true).finally(function() { | ||
var innerf = new Future | ||
innerf.throw("test") | ||
f.return() | ||
return innerf | ||
}).done() | ||
}) | ||
}) | ||
this.test("exception in returned future, passed to a catch", function(t) { | ||
@@ -515,5 +424,5 @@ this.count(1) | ||
}) | ||
}).done() | ||
}) | ||
//*/ | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
14
236
348963
8955
8
1