Skip to content

Commit

Permalink
Merge pull request kriskowal#643
Browse files Browse the repository at this point in the history
  • Loading branch information
kriskowal committed Apr 26, 2015
2 parents 1cf5914 + 86cb5c6 commit 1c38507
Showing 1 changed file with 67 additions and 31 deletions.
98 changes: 67 additions & 31 deletions q.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ var nextTick =(function () {
var flushing = false;
var requestTick = void 0;
var isNodeJS = false;
// queue for late tasks, used by unhandled rejection tracking
var laterQueue = [];

function flush() {
/* jshint loopfunc: true */
Expand All @@ -105,43 +107,50 @@ var nextTick =(function () {
head.domain = void 0;
domain.enter();
}
runSingle(task, domain);

try {
task();

} catch (e) {
if (isNodeJS) {
// In node, uncaught exceptions are considered fatal errors.
// Re-throw them synchronously to interrupt flushing!

// Ensure continuation if the uncaught exception is suppressed
// listening "uncaughtException" events (as domains does).
// Continue in next event to avoid tick recursion.
if (domain) {
domain.exit();
}
setTimeout(flush, 0);
if (domain) {
domain.enter();
}

throw e;
}
while(laterQueue.length){
var fn = laterQueue.pop();
runSingle(fn);
}
flushing = false;
}
// runs a single function in the async queue
function runSingle(task, domain){
try {
task();

} else {
// In browsers, uncaught exceptions are not fatal.
// Re-throw them asynchronously to avoid slow-downs.
setTimeout(function() {
throw e;
}, 0);
} catch (e) {
if (isNodeJS) {
// In node, uncaught exceptions are considered fatal errors.
// Re-throw them synchronously to interrupt flushing!

// Ensure continuation if the uncaught exception is suppressed
// listening "uncaughtException" events (as domains does).
// Continue in next event to avoid tick recursion.
if (domain) {
domain.exit();
}
setTimeout(flush, 0);
if (domain) {
domain.enter();
}
}

if (domain) {
domain.exit();
throw e;

} else {
// In browsers, uncaught exceptions are not fatal.
// Re-throw them asynchronously to avoid slow-downs.
setTimeout(function() {
throw e;
}, 0);
}
}

flushing = false;
if (domain) {
domain.exit();
}
}

nextTick = function (task) {
Expand Down Expand Up @@ -210,7 +219,16 @@ var nextTick =(function () {
setTimeout(flush, 0);
};
}

// runs a task after all other tasks have been run
// this is useful for unhandled rejection tracking that needs to happen
// after all `then`d tasks have been run.
nextTick.runAfter = function(task){
laterQueue.push(task);
if (!flushing) {
flushing = true;
requestTick();
}
};
return nextTick;
})();

Expand Down Expand Up @@ -1004,6 +1022,7 @@ Promise.prototype.isRejected = function () {
// shimmed environments, this would naturally be a `Set`.
var unhandledReasons = [];
var unhandledRejections = [];
var reportedUnhandledRejections = [];
var trackUnhandledRejections = true;

function resetUnhandledRejections() {
Expand All @@ -1019,6 +1038,14 @@ function trackRejection(promise, reason) {
if (!trackUnhandledRejections) {
return;
}
if(typeof process === "object" && typeof process.emit === "function") {
Q.nextTick.runAfter(function() {
if(array_indexOf(unhandledRejections, promise) !== -1) {
process.emit("unhandledRejection", reason, promise);
reportedUnhandledRejections.push(promise);
}
});
}

unhandledRejections.push(promise);
if (reason && typeof reason.stack !== "undefined") {
Expand All @@ -1035,6 +1062,15 @@ function untrackRejection(promise) {

var at = array_indexOf(unhandledRejections, promise);
if (at !== -1) {
if(typeof process === "object" && typeof process.emit === "function") {
Q.nextTick.runAfter(function() {
var atReport = array_indexOf(reportedUnhandledRejections, promise);
if(atReport !== -1) {
process.emit("rejectionHandled", unhandledReasons[at], promise);
reportedUnhandledRejections.splice(atReport, 1);
}
});
}
unhandledRejections.splice(at, 1);
unhandledReasons.splice(at, 1);
}
Expand Down

0 comments on commit 1c38507

Please sign in to comment.