Skip to content

Commit 7a30a78

Browse files
committed
feat: Promise.lazy
Constructor for lazy promises
1 parent 78ed73b commit 7a30a78

File tree

6 files changed

+102
-0
lines changed

6 files changed

+102
-0
lines changed

index.js

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ module.exports = {
1616
math: require("./math"),
1717
number: require("./number"),
1818
object: require("./object"),
19+
promise: require("./promise"),
1920
regExp: require("./reg-exp"),
2021
string: require("./string")
2122
};

promise/.eslintrc.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"globals": { "Promise": true }
3+
}

promise/index.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"use strict";
2+
3+
module.exports = {
4+
lazy: require("./lazy")
5+
};

promise/lazy.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"use strict";
2+
3+
var isFunction = require("../function/is-function");
4+
5+
module.exports = function (executor) {
6+
var Constructor;
7+
if (isFunction(this)) {
8+
Constructor = this;
9+
} else if (typeof Promise === "function") {
10+
Constructor = Promise;
11+
} else {
12+
throw new TypeError("Could not resolve Promise constuctor");
13+
}
14+
15+
var lazyThen;
16+
var promise = new Constructor(function (resolve, reject) {
17+
lazyThen = function (onSuccess, onFailure) {
18+
if (!hasOwnProperty.call(this, "then")) {
19+
// Sanity check
20+
throw new Error("Unexpected (inherited) lazy then invocation");
21+
}
22+
23+
try {
24+
executor(resolve, reject);
25+
} catch (reason) {
26+
reject(reason);
27+
}
28+
delete this.then;
29+
return this.then(onSuccess, onFailure);
30+
};
31+
});
32+
33+
return Object.defineProperty(promise, "then", {
34+
configurable: true,
35+
writable: true,
36+
value: lazyThen
37+
});
38+
};

test/promise/.eslintrc.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"globals": { "setTimeout": true }
3+
}

test/promise/lazy.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"use strict";
2+
3+
module.exports = function (t) {
4+
if (typeof Promise !== "function") return null; // Run tests only in ES2015+ env
5+
6+
return {
7+
"Delays execution": function (a, d) {
8+
var invoked = false;
9+
var promise = t(function (resolve) {
10+
invoked = true;
11+
setTimeout(function () {
12+
resolve(20);
13+
}, 10);
14+
});
15+
16+
a(invoked, false);
17+
18+
setTimeout(function () {
19+
a(invoked, false);
20+
promise.then(function (value) {
21+
a(value, 20);
22+
setTimeout(d, 0); // Escape error swallowing
23+
});
24+
a(invoked, true);
25+
}, 15);
26+
},
27+
"Passes rejection": function (a, d) {
28+
var promise = t(function (resolve, reject) {
29+
setTimeout(function () {
30+
reject(new Error("Stop"));
31+
}, 10);
32+
});
33+
34+
promise.catch(function (error) {
35+
a(error instanceof Error, true);
36+
a(error.message, "Stop");
37+
setTimeout(d, 0); // Escape error swallowing
38+
});
39+
},
40+
"Passes sync exception": function (a, d) {
41+
var promise = t(function () {
42+
throw new Error("Stop");
43+
});
44+
45+
promise.catch(function (error) {
46+
a(error instanceof Error, true);
47+
a(error.message, "Stop");
48+
setTimeout(d, 0); // Escape error swallowing
49+
});
50+
}
51+
};
52+
};

0 commit comments

Comments
 (0)