Skip to content

Commit 794cc8b

Browse files
committed
await
1 parent aa2d748 commit 794cc8b

File tree

11 files changed

+124
-53
lines changed

11 files changed

+124
-53
lines changed

lib/functions/parallel.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ function promiseHandler(index, data) {
66
this.resolve(this.results);
77
}
88
else {
9-
execute(this);
9+
process(this);
1010
}
1111
}
12-
function execute(scope) {
12+
function process(scope) {
1313
if (scope.processes < scope.maxThreads && scope.pointer < scope.tasks.length) {
1414
var handler = promiseHandler.bind(scope, scope.pointer);
1515
scope.tasks[scope.pointer]().then(handler, handler);
@@ -35,7 +35,7 @@ function parallel(tasks, maxThreads) {
3535
for (var i = 0; i < maxThreads && i < tasks.length; i++) {
3636
scope.resolve = resolve;
3737
scope.reject = reject;
38-
execute(scope);
38+
process(scope);
3939
}
4040
});
4141
}

lib/functions/retry.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
import { ITask } from "../types";
2-
export declare function retry(task: ITask, times?: number, delay?: number): Promise<any>;
2+
export declare function retry(task: ITask, times?: number, delay?: number, timeout?: number): Promise<any>;

lib/functions/retry.js

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,50 @@
11
"use strict";
2+
var types_1 = require("../types");
23
var prow = require("../prow");
3-
function process(task, times, reasons, delay, resolve, reject) {
4-
return task().then(function (result) {
5-
resolve(result);
4+
function process(scope) {
5+
return scope.task().then(function (result) {
6+
clearTimeout(scope.timeoutId);
7+
scope.resolve(result);
68
}).catch(function (reason) {
7-
reasons.push(reason);
8-
if (reasons.length >= times && times >= 0) {
9-
reject(reasons);
9+
scope.reasons.push(reason);
10+
if (scope.reasons.length >= scope.times && scope.times >= 0) {
11+
clearTimeout(scope.timeoutId);
12+
scope.reject(scope.reasons);
1013
}
11-
else {
12-
if (delay > 0) {
13-
prow.delay(delay).then(function () { return process(task, times, reasons, delay, resolve, reject); });
14+
else if (!scope.cancelled) {
15+
if (scope.delay > 0) {
16+
prow.delay(scope.delay).then(function () { return process(scope); });
1417
}
1518
else {
16-
process(task, times, reasons, delay, resolve, reject);
19+
process(scope);
1720
}
1821
}
1922
});
2023
}
21-
function retry(task, times, delay) {
24+
function retry(task, times, delay, timeout) {
2225
if (times === void 0) { times = -1; }
2326
if (delay === void 0) { delay = 0; }
27+
if (timeout === void 0) { timeout = -1; }
2428
return new Promise(function (resolve, reject) {
2529
var reasons = [];
26-
process(task, times, reasons, delay, resolve, reject);
30+
var scope = {
31+
task: task,
32+
times: times,
33+
reasons: reasons,
34+
delay: delay,
35+
timeout: timeout,
36+
cancelled: false,
37+
timeoutId: -1,
38+
resolve: resolve,
39+
reject: reject
40+
};
41+
if (timeout >= 0) {
42+
scope.timeoutId = setTimeout(function () {
43+
scope.cancelled = true;
44+
reject(new types_1.TimeoutError());
45+
}, timeout);
46+
}
47+
process(scope);
2748
});
2849
}
2950
exports.retry = retry;

lib/functions/timeout.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
import { ITask } from "../types";
2-
export declare function timeout(task: ITask, time: number): Promise<any>;
2+
export declare function timeout(task: ITask, timeout: number): Promise<any>;

lib/functions/timeout.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
"use strict";
22
var types_1 = require("../types");
3-
function timeout(task, time) {
3+
function timeout(task, timeout) {
44
return new Promise(function (resolve, reject) {
5-
var timeout = -1;
6-
if (time >= 0) {
7-
timeout = setTimeout(reject.bind(null, new types_1.TimeoutError()), time);
5+
var timeoutId = -1;
6+
if (timeout >= 0) {
7+
timeoutId = setTimeout(reject.bind(null, new types_1.TimeoutError()), timeout);
88
}
99
task().then(function (result) {
1010
resolve(result);
11-
clearTimeout(timeout);
11+
clearTimeout(timeoutId);
1212
}, function (reason) {
1313
reject(reason);
14-
clearTimeout(timeout);
14+
clearTimeout(timeoutId);
1515
});
1616
});
1717
}

lib/types.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/// <reference types="node" />
21
export interface ITask {
32
(...args: any[]): Promise<any>;
43
}

src/functions/await.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,12 @@ import * as prow from "../prow";
1212
* @returns Promise
1313
*/
1414
export function await(condition: ITask, delay: number, timeout: number = -1): Promise<any> {
15-
const promise = new Promise(function (resolve) {
15+
return new Promise(function (resolve, reject) {
1616
const conditionHandler = (result) => {
1717
if (result) {
1818
resolve();
1919
}
2020
};
21-
prow.retry(condition, -1, delay).then(conditionHandler);
21+
prow.retry(condition, -1, delay, timeout).then(conditionHandler).catch(reject);
2222
});
23-
24-
return prow.timeout(() => promise, timeout);
2523
}

src/functions/parallel.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ function promiseHandler (index: number, data: any) {
1818
if (this.processes === 0 && index === this.tasks.length - 1) {
1919
this.resolve(this.results);
2020
} else {
21-
execute(this);
21+
process(this);
2222
}
2323
}
2424

25-
function execute(scope: IScope) {
25+
function process(scope: IScope) {
2626
if (scope.processes < scope.maxThreads && scope.pointer < scope.tasks.length) {
2727
const handler = promiseHandler.bind(scope, scope.pointer);
2828
scope.tasks[scope.pointer]().then(handler, handler);
@@ -50,7 +50,7 @@ export function parallel(tasks: Tasks, maxThreads: number = tasks.length): Promi
5050
for (let i = 0; i < maxThreads && i < tasks.length; i++) {
5151
scope.resolve = resolve;
5252
scope.reject = reject;
53-
execute(scope);
53+
process(scope);
5454
}
5555
});
5656
}

src/functions/retry.ts

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,62 @@
11
import {
2-
ITask
2+
ITask, TimeoutError
33
} from "../types";
44

55
import * as prow from "../prow";
66

7-
function process(task: ITask, times: number, reasons: any[], delay, resolve, reject): Promise<any> {
8-
return task().then((result) => {
9-
resolve(result);
7+
interface IScope {
8+
task: ITask;
9+
times: number;
10+
reasons: any[];
11+
delay: number;
12+
timeout: number;
13+
cancelled: boolean;
14+
timeoutId: number;
15+
resolve: any;
16+
reject: any;
17+
}
18+
19+
function process(scope: IScope): Promise<any> {
20+
return scope.task().then((result) => {
21+
clearTimeout(scope.timeoutId);
22+
scope.resolve(result);
1023
}).catch((reason) => {
11-
reasons.push(reason);
12-
if (reasons.length >= times && times >= 0) {
13-
reject(reasons);
14-
} else {
15-
if (delay > 0) {
16-
prow.delay(delay).then(() => process(task, times, reasons, delay, resolve, reject));
24+
scope.reasons.push(reason);
25+
if (scope.reasons.length >= scope.times && scope.times >= 0) {
26+
clearTimeout(scope.timeoutId);
27+
scope.reject(scope.reasons);
28+
} else if (!scope.cancelled) {
29+
if (scope.delay > 0) {
30+
prow.delay(scope.delay).then(() => process(scope));
1731
} else {
18-
process(task, times, reasons, delay, resolve, reject);
32+
process(scope);
1933
}
2034
}
2135
});
2236
}
2337

24-
export function retry(task: ITask, times: number = -1, delay: number = 0): Promise<any> {
38+
export function retry(task: ITask, times: number = -1, delay: number = 0, timeout: number = -1): Promise<any> {
2539
return new Promise(function (resolve, reject) {
2640
const reasons = [];
27-
process(task, times, reasons, delay, resolve, reject);
41+
const scope = {
42+
task,
43+
times,
44+
reasons,
45+
delay,
46+
timeout,
47+
cancelled: false,
48+
timeoutId: -1,
49+
resolve,
50+
reject
51+
};
52+
53+
if (timeout >= 0) {
54+
scope.timeoutId = setTimeout(() => {
55+
scope.cancelled = true;
56+
reject(new TimeoutError());
57+
}, timeout);
58+
}
59+
60+
process(scope);
2861
});
2962
}

src/functions/timeout.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ import {
22
ITask, TimeoutError
33
} from "../types";
44

5-
export function timeout(task: ITask, time: number): Promise<any> {
5+
export function timeout(task: ITask, timeout: number): Promise<any> {
66
return new Promise(function (resolve, reject) {
7-
let timeout = -1;
8-
if (time >= 0) {
9-
timeout = setTimeout(reject.bind(null, new TimeoutError()), time);
7+
let timeoutId = -1;
8+
if (timeout >= 0) {
9+
timeoutId = setTimeout(reject.bind(null, new TimeoutError()), timeout);
1010
}
1111

1212
task().then((result) => {
1313
resolve(result);
14-
clearTimeout(timeout);
14+
clearTimeout(timeoutId);
1515
}, (reason) => {
1616
reject(reason);
17-
clearTimeout(timeout);
17+
clearTimeout(timeoutId);
1818
});
1919
});
2020
}

test/retry.js

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function resolvePromise(value) {
1414
}
1515
}
1616

17-
function promiseRejected(rejectedTimes, resolveValue) {
17+
function promiseReject(rejectedTimes, resolveValue) {
1818
let counter = 0;
1919
return function () {
2020
if (counter++ < rejectedTimes) {
@@ -24,18 +24,38 @@ function promiseRejected(rejectedTimes, resolveValue) {
2424
}
2525
}
2626

27+
function delayedReject(delayTime, rejectValue) {
28+
return function() {
29+
return new Promise((resolve, reject) => {
30+
setTimeout(() => {
31+
reject(rejectValue);
32+
}, delayTime);
33+
});
34+
}
35+
}
36+
2737
describe("Retry", function () {
2838
it("resolve", function () {
2939
return assert.becomes(prow.retry(resolvePromise("resolve"), 1), "resolve");
3040
});
3141

3242
it("reject 5 times", function () {
33-
return prow.retry(promiseRejected(5, null), 5).catch((data) => {
43+
return prow.retry(promiseReject(5, null), 5).catch((data) => {
3444
assert.deepEqual(data, [1, 2, 3, 4, 5])
3545
});
3646
});
3747

3848
it("reject 5 times, resolve on 6th", function () {
39-
return assert.becomes(prow.retry(promiseRejected(5, 42), 6), 42);
49+
return assert.becomes(prow.retry(promiseReject(5, 42), 6), 42);
50+
});
51+
52+
it("reject by timeout", function () {
53+
return assert.isRejected(prow.retry(delayedReject(50, null), 5, 0, 200), prow.TimeoutError);
54+
});
55+
56+
it("timeout, not rejected", function () {
57+
return prow.retry(delayedReject(50, null), 5, 0, 300).catch((data) => {
58+
assert.deepEqual(data, [null, null, null, null, null])
59+
});
4060
});
4161
});

0 commit comments

Comments
 (0)