Skip to content

Commit 61cac06

Browse files
authored
Merge pull request #250 from bekzod/new-set-timeout
add error stack to `.later`
2 parents fc747b1 + c50165b commit 61cac06

File tree

3 files changed

+64
-40
lines changed

3 files changed

+64
-40
lines changed

lib/backburner/binary-search.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
export default function binarySearch(time, timers) {
22
let start = 0;
3-
let end = timers.length - 2;
3+
let end = timers.length - 6;
44
let middle;
55
let l;
66

77
while (start < end) {
88
// since timers is an array of pairs 'l' will always
99
// be an integer
10-
l = (end - start) / 2;
10+
l = (end - start) / 6;
1111

1212
// compensate for the index in case even number
1313
// of pairs inside timers
14-
middle = start + l - (l % 2);
14+
middle = start + l - (l % 6);
1515

1616
if (time >= timers[middle]) {
17-
start = middle + 2;
17+
start = middle + 6;
1818
} else {
1919
end = middle;
2020
}
2121
}
2222

23-
return (time >= timers[start]) ? start + 2 : start;
23+
return (time >= timers[start]) ? start + 6 : start;
2424
}

lib/index.ts

+24-33
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ function parseArgs() {
4343
return [target, method, args];
4444
}
4545

46+
let UUID = 0;
47+
4648
export default class Backburner {
4749
public static Queue = Queue;
4850

@@ -327,25 +329,7 @@ export default class Backburner {
327329
}
328330
}
329331

330-
let onError = getOnError(this.options);
331-
let executeAt = this._platform.now() + wait;
332-
333-
let fn;
334-
if (onError) {
335-
fn = function() {
336-
try {
337-
method.apply(target, args);
338-
} catch (e) {
339-
onError(e);
340-
}
341-
};
342-
} else {
343-
fn = function() {
344-
method.apply(target, args);
345-
};
346-
}
347-
348-
return this._setTimeout(fn, executeAt);
332+
return this._setTimeout(target, method, args, wait);
349333
}
350334

351335
public throttle<T>(target: T, methodName: keyof T, wait?: number | string, immediate?: boolean): Timer;
@@ -530,9 +514,9 @@ export default class Backburner {
530514
if (!timer) { return false; }
531515
let timerType = typeof timer;
532516

533-
if (timerType === 'number' || timerType === 'string') { // we're cancelling a throttle or debounce
517+
if (timerType === 'number') { // we're cancelling a throttle or debounce
534518
return this._cancelItem(timer, this._throttlers) || this._cancelItem(timer, this._debouncees);
535-
} else if (timerType === 'function') { // we're cancelling a setTimeout
519+
} else if (timerType === 'string') { // we're cancelling a setTimeout
536520
return this._cancelLaterTimer(timer);
537521
} else if (timerType === 'object' && timer.queue && timer.method) { // we're cancelling a deferOnce
538522
return timer.queue.cancel(timer);
@@ -586,31 +570,34 @@ export default class Backburner {
586570
}
587571
}
588572

589-
private _setTimeout(fn, executeAt) {
573+
private _setTimeout(target, method, args, wait) {
574+
let stack = this.DEBUG ? new Error() : undefined;
575+
let executeAt = this._platform.now() + wait;
576+
let id = (UUID++) + '';
577+
590578
if (this._timers.length === 0) {
591-
this._timers.push(executeAt, fn);
579+
this._timers.push(executeAt, id, target, method, args, stack);
592580
this._installTimerTimeout();
593-
return fn;
581+
return id;
594582
}
595583

596584
// find position to insert
597585
let i = searchTimer(executeAt, this._timers);
598-
599-
this._timers.splice(i, 0, executeAt, fn);
586+
this._timers.splice(i, 0, executeAt, id, target, method, args, stack);
600587

601588
// we should be the new earliest timer if i == 0
602589
if (i === 0) {
603590
this._reinstallTimerTimeout();
604591
}
605592

606-
return fn;
593+
return id;
607594
}
608595

609596
private _cancelLaterTimer(timer) {
610-
for (let i = 1; i < this._timers.length; i += 2) {
597+
for (let i = 1; i < this._timers.length; i += 6) {
611598
if (this._timers[i] === timer) {
612599
i = i - 1;
613-
this._timers.splice(i, 2); // remove the two elements
600+
this._timers.splice(i, 6);
614601
if (i === 0) {
615602
this._reinstallTimerTimeout();
616603
}
@@ -662,15 +649,19 @@ export default class Backburner {
662649

663650
private _scheduleExpiredTimers() {
664651
let timers = this._timers;
665-
let l = timers.length;
666652
let i = 0;
653+
let l = timers.length;
667654
let defaultQueue = this.options.defaultQueue;
668655
let n = this._platform.now();
669-
for (; i < l; i += 2) {
656+
657+
for (; i < l; i += 6) {
670658
let executeAt = timers[i];
671659
if (executeAt <= n) {
672-
let fn = timers[i + 1];
673-
this.schedule(defaultQueue, null, fn);
660+
let target = timers[i + 2];
661+
let method = timers[i + 3];
662+
let args = timers[i + 4];
663+
let stack = timers[i + 5];
664+
this.currentInstance!.schedule(defaultQueue, target, method, args, false, stack);
674665
} else {
675666
break;
676667
}

tests/debug-test.ts

+35-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Backburner from 'backburner';
22

33
QUnit.module('tests/debug');
44

5-
QUnit.test('DEBUG flag enables stack tagging', function(assert) {
5+
QUnit.test('schedule - DEBUG flag enables stack tagging', function(assert) {
66
let bb = new Backburner(['one']);
77

88
bb.schedule('one', () => {});
@@ -26,7 +26,7 @@ QUnit.test('DEBUG flag enables stack tagging', function(assert) {
2626
assert.ok(errorRecordedForStack.stack, 'stack is recorded');
2727
};
2828

29-
bb = new Backburner(['errors'], {onError: onError});
29+
bb = new Backburner(['errors'], { onError });
3030
bb.DEBUG = true;
3131

3232
bb.run(() => {
@@ -36,3 +36,36 @@ QUnit.test('DEBUG flag enables stack tagging', function(assert) {
3636
});
3737
}
3838
});
39+
40+
QUnit.test('later - DEBUG flag off does not capture stack', function(assert) {
41+
let done = assert.async();
42+
let onError = function(error, errorRecordedForStack) {
43+
assert.strictEqual(errorRecordedForStack, undefined, 'errorRecordedForStack is not passed to error function when DEBUG is not set');
44+
done();
45+
};
46+
let bb = new Backburner(['one'], { onError });
47+
48+
bb.later(() => {
49+
throw new Error('message!');
50+
});
51+
});
52+
53+
if (new Error().stack) { // workaround for CLI runner :(
54+
QUnit.test('later - DEBUG flag on captures stack', function(assert) {
55+
assert.expect(3);
56+
57+
let done = assert.async();
58+
let onError = function(error, errorRecordedForStack) {
59+
assert.ok(errorRecordedForStack, 'errorRecordedForStack passed to error function');
60+
assert.ok(errorRecordedForStack.stack, 'stack is recorded');
61+
assert.ok(errorRecordedForStack.stack.indexOf('later') > -1, 'stack includes `later` invocation');
62+
done();
63+
};
64+
let bb = new Backburner(['one'], { onError });
65+
bb.DEBUG = true;
66+
67+
bb.later(() => {
68+
throw new Error('message!');
69+
});
70+
});
71+
}

0 commit comments

Comments
 (0)