@util.js/promises 0.41.5 → 0.41.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -1
- package/doc/README-examples.js +0 -203
- package/lib/Promises.js +0 -411
- package/test/PromisesTest.js +0 -477
package/package.json
CHANGED
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
"work in https://npm.runkit.com."
|
|
9
9
|
],
|
|
10
10
|
"description": "JavaScript utility methods for promises",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"index.js"
|
|
14
|
+
],
|
|
11
15
|
"keywords": [
|
|
12
16
|
"promise",
|
|
13
17
|
"promises",
|
|
@@ -28,5 +32,5 @@
|
|
|
28
32
|
"type": "git",
|
|
29
33
|
"url": "https://github.com/creemama/utiljs/tree/master/packages/utiljs-promises"
|
|
30
34
|
},
|
|
31
|
-
"version": "0.41.
|
|
35
|
+
"version": "0.41.7"
|
|
32
36
|
}
|
package/doc/README-examples.js
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
if (process.argv.length < 3) {
|
|
4
|
-
for (let i = 0; i < 10; i++) runExample(i);
|
|
5
|
-
} else {
|
|
6
|
-
runExample(parseInt(process.argv[2]));
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
function runExample(i) {
|
|
10
|
-
switch (i) {
|
|
11
|
-
case 0:
|
|
12
|
-
runExample0();
|
|
13
|
-
break;
|
|
14
|
-
case 1:
|
|
15
|
-
runExample1();
|
|
16
|
-
break;
|
|
17
|
-
case 2:
|
|
18
|
-
runExample2();
|
|
19
|
-
break;
|
|
20
|
-
case 3:
|
|
21
|
-
runExample3();
|
|
22
|
-
break;
|
|
23
|
-
case 4:
|
|
24
|
-
runExample4();
|
|
25
|
-
break;
|
|
26
|
-
case 5:
|
|
27
|
-
runExample5();
|
|
28
|
-
break;
|
|
29
|
-
case 6:
|
|
30
|
-
runExample6();
|
|
31
|
-
break;
|
|
32
|
-
case 7:
|
|
33
|
-
runExample7();
|
|
34
|
-
break;
|
|
35
|
-
case 8:
|
|
36
|
-
runExample8();
|
|
37
|
-
break;
|
|
38
|
-
case 9:
|
|
39
|
-
runExample9();
|
|
40
|
-
break;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function runExample0() {
|
|
45
|
-
const promises = require("..");
|
|
46
|
-
const promise1 = Promise.resolve(3);
|
|
47
|
-
const promise2 = 42;
|
|
48
|
-
const promise3 = new Promise((resolve, reject) => {
|
|
49
|
-
setTimeout(resolve, 100, "foo");
|
|
50
|
-
});
|
|
51
|
-
promises.all(promise1, promise2, promise3).then((values) => {
|
|
52
|
-
console.log(values);
|
|
53
|
-
});
|
|
54
|
-
// expected output: Array [3, 42, "foo"]
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function runExample1() {
|
|
58
|
-
// Wrap a function that only accepts a callback.
|
|
59
|
-
const promises = require("..");
|
|
60
|
-
const stream = require("stream");
|
|
61
|
-
const streams = require("../../utiljs-streams");
|
|
62
|
-
// stream#finished only takes a callback.
|
|
63
|
-
// Wrap stream#finished so that it handles both callbacks and Promises.
|
|
64
|
-
function finished() {
|
|
65
|
-
return promises.applyCallback(stream, stream.finished, arguments);
|
|
66
|
-
}
|
|
67
|
-
const readableToCallback = streams.fromString("Call back, Hypnotoad!");
|
|
68
|
-
finished(readableToCallback, () => console.log("Finished with a callback"));
|
|
69
|
-
const readableToPromise = streams.fromString("Promise me, Hypnotoad!");
|
|
70
|
-
finished(readableToPromise).then(() => console.log("Finished as promised"));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function runExample2() {
|
|
74
|
-
// Write a function that supports both callbacks and Promises.
|
|
75
|
-
const promises = require("..");
|
|
76
|
-
function notify(message, who, callback) {
|
|
77
|
-
if (!callback) return promises.applyCallback(null, notify, arguments);
|
|
78
|
-
callback(null, `${message}, ${who}!`);
|
|
79
|
-
}
|
|
80
|
-
notify("Call back", "Hypnotoad", (error, message) => {
|
|
81
|
-
if (error) {
|
|
82
|
-
console.error(error);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
console.log(message);
|
|
86
|
-
});
|
|
87
|
-
notify("Promise me", "Hypnotoad").then(console.log);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function runExample3() {
|
|
91
|
-
// Wrap a function that only returns a Promise.
|
|
92
|
-
const promises = require("..");
|
|
93
|
-
function notifyPromise(message, who) {
|
|
94
|
-
return promises.resolve(`${message}, ${who}!`);
|
|
95
|
-
}
|
|
96
|
-
// #notifyPromise only returns a Promise.
|
|
97
|
-
// Wrap #notifyPromise so that it handles both callbacks and Promises.
|
|
98
|
-
function notify(message, who, callback) {
|
|
99
|
-
return promises.applyPromise(null, notifyPromise, arguments);
|
|
100
|
-
}
|
|
101
|
-
notify("Call back", "Hypnotoad", (error, message) => {
|
|
102
|
-
if (error) {
|
|
103
|
-
console.error(error);
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
console.log(message);
|
|
107
|
-
});
|
|
108
|
-
notify("Promise me", "Hypnotoad").then(console.log);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function runExample4() {
|
|
112
|
-
// Write a function that supports both callbacks and Promises.
|
|
113
|
-
const promises = require("..");
|
|
114
|
-
function notify(message, who, callback) {
|
|
115
|
-
if (callback) return promises.applyPromise(null, notify, arguments);
|
|
116
|
-
return promises.resolve(`${message}, ${who}!`);
|
|
117
|
-
}
|
|
118
|
-
notify("Call back", "Hypnotoad", (error, message) => {
|
|
119
|
-
if (error) {
|
|
120
|
-
console.error(error);
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
console.log(message);
|
|
124
|
-
});
|
|
125
|
-
notify("Promise me", "Hypnotoad").then(console.log);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function runExample5() {
|
|
129
|
-
const promises = require("..");
|
|
130
|
-
function notifyPromise(message, who) {
|
|
131
|
-
return promises.resolve(`${message}, ${who}!`);
|
|
132
|
-
}
|
|
133
|
-
// #notifyPromise only returns a Promise.
|
|
134
|
-
// Wrap #notifyPromise so that it accepts a callback.
|
|
135
|
-
const notify = promises.callbackify(notifyPromise);
|
|
136
|
-
notify("Call back", "Hypnotoad", (error, message) => {
|
|
137
|
-
if (error) {
|
|
138
|
-
console.error(error);
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
console.log(message);
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function runExample6() {
|
|
146
|
-
const promises = require("..");
|
|
147
|
-
function notifyCallback(message, who, callback) {
|
|
148
|
-
callback(null, `${message}, ${who}!`);
|
|
149
|
-
}
|
|
150
|
-
// #notifyCallback only accpets a callback.
|
|
151
|
-
// Force #notifyCallback to return a Promise.
|
|
152
|
-
promises
|
|
153
|
-
.callCallback(null, notifyCallback, "Promise me", "Hypnotoad")
|
|
154
|
-
.then(console.log);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function runExample7() {
|
|
158
|
-
const promises = require("..");
|
|
159
|
-
function notifyPromise(message, who) {
|
|
160
|
-
return promises.resolve(`${message}, ${who}!`);
|
|
161
|
-
}
|
|
162
|
-
// #notifyPromise only returns a Promise.
|
|
163
|
-
// Force #notifyPromise to accept a callback.
|
|
164
|
-
promises.callPromise(
|
|
165
|
-
null,
|
|
166
|
-
notifyPromise,
|
|
167
|
-
"Call back",
|
|
168
|
-
"Hypnotoad",
|
|
169
|
-
(error, message) => {
|
|
170
|
-
if (error) {
|
|
171
|
-
console.error(error);
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
console.log(message);
|
|
175
|
-
},
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function runExample8() {
|
|
180
|
-
const promises = require("..");
|
|
181
|
-
const stream = require("stream");
|
|
182
|
-
const streams = require("../../utiljs-streams");
|
|
183
|
-
// stream#finished only takes a callback.
|
|
184
|
-
// Let us wrap stream#finished so that it returns a Promise.
|
|
185
|
-
const readable = streams.fromString("Promise me, Hypnotoad!");
|
|
186
|
-
const finished = promises.promisify(stream.finished);
|
|
187
|
-
finished(readable).then(() => console.log("Finished as promised"));
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function runExample9() {
|
|
191
|
-
const promises = require("..");
|
|
192
|
-
const promise1 = new Promise((resolve, reject) => {
|
|
193
|
-
setTimeout(resolve, 500, "one");
|
|
194
|
-
});
|
|
195
|
-
const promise2 = new Promise((resolve, reject) => {
|
|
196
|
-
setTimeout(resolve, 100, "two");
|
|
197
|
-
});
|
|
198
|
-
promises.race(promise1, promise2).then((value) => {
|
|
199
|
-
console.log(value);
|
|
200
|
-
// Both resolve, but promise2 is faster
|
|
201
|
-
});
|
|
202
|
-
// expected output: "two"
|
|
203
|
-
}
|
package/lib/Promises.js
DELETED
|
@@ -1,411 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* JavaScript utility methods for [promises]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise}
|
|
5
|
-
* @public
|
|
6
|
-
* @class
|
|
7
|
-
*/
|
|
8
|
-
class Promises {
|
|
9
|
-
/**
|
|
10
|
-
* Returns a single Promise that resolves when all of the promises in the iterable argument have resolved or when the iterable argument contains no promises.
|
|
11
|
-
*
|
|
12
|
-
* It rejects with the reason of the first promise that rejects.
|
|
13
|
-
*
|
|
14
|
-
* See MDN's documentation about [all]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all}.
|
|
15
|
-
*
|
|
16
|
-
* There is one minor difference between Promise#all and this method. Promise#all only takes one argument that must be iterable. This method, Promises#all, behaves the same as Promise#all when given one argument; when given multiple arguments, [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments} becomes the iterable.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* const promises = require("@util.js/promises");
|
|
20
|
-
* const promise1 = Promise.resolve(3);
|
|
21
|
-
* const promise2 = 42;
|
|
22
|
-
* const promise3 = new Promise((resolve, reject) => {
|
|
23
|
-
* setTimeout(resolve, 100, "foo");
|
|
24
|
-
* });
|
|
25
|
-
* promises.all(promise1, promise2, promise3).then(values => {
|
|
26
|
-
* console.log(values);
|
|
27
|
-
* });
|
|
28
|
-
* // expected output: Array [3, 42, "foo"]
|
|
29
|
-
*
|
|
30
|
-
* @param {iterable|...*} iterable An iterable object such as an Array or String; if you give move than one argument to this method, [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments} becomes the iterable
|
|
31
|
-
* @return {Promise} (A) An already resolved Promise if the iterable passed is empty.
|
|
32
|
-
* (B) An asynchronously resolved Promise if the iterable passed contains no promises.
|
|
33
|
-
* (C) A pending Promise in all other cases; this returned promise is then resolved/rejected asynchronously (as soon as the stack is empty) when all the promises in the given iterable have resolved, or if any of the promises reject; returned values will be in order of the Promises passed, regardless of completion order.
|
|
34
|
-
* @public
|
|
35
|
-
* @instance
|
|
36
|
-
* @function
|
|
37
|
-
*/
|
|
38
|
-
all() {
|
|
39
|
-
if (arguments.length > 1) return Promise.all(arguments);
|
|
40
|
-
return Promise.all(...arguments);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Calls the given functionOnObjectWithCallback with the given args that either (A) returns a Promise if args does not contain a callback or (B) notifies the callback if args contains a callback.
|
|
45
|
-
*
|
|
46
|
-
* Use this function if you are wrapping an existing function that only takes a callback but would like that function to handle both callbacks and Promises.
|
|
47
|
-
*
|
|
48
|
-
* It is also useful in writing new functions where you would like to support both callbacks and Promises.
|
|
49
|
-
*
|
|
50
|
-
* This function adapts functions that accept a callback. {@link Promises#applyPromise} adapts functions that return a Promise.
|
|
51
|
-
*
|
|
52
|
-
* This function is similar to Function#apply. It accepts a single array of arguments.
|
|
53
|
-
*
|
|
54
|
-
* Function#call and {@link Promises#callCallback} accept an argument list.
|
|
55
|
-
*
|
|
56
|
-
* When trying to remember the difference between #apply and #call, think, "#apply accepts an array. Both array and #apply start with a."
|
|
57
|
-
*
|
|
58
|
-
* @example
|
|
59
|
-
* // Wrap a function that only accepts a callback.
|
|
60
|
-
* const promises = require("@util.js/promises");
|
|
61
|
-
* const stream = require("stream");
|
|
62
|
-
* const streams = require("@util.js/node-streams");
|
|
63
|
-
* // stream#finished only takes a callback.
|
|
64
|
-
* // Wrap stream#finished so that it handles both callbacks and Promises.
|
|
65
|
-
* function finished() {
|
|
66
|
-
* return promises.applyCallback(stream, stream.finished, arguments);
|
|
67
|
-
* }
|
|
68
|
-
* const readableToCallback = streams.fromString("Call back, Hypnotoad!");
|
|
69
|
-
* finished(readableToCallback, () => console.log("Finished with a callback"));
|
|
70
|
-
* const readableToPromise = streams.fromString("Promise me, Hypnotoad!");
|
|
71
|
-
* finished(readableToPromise).then(() => console.log("Finished as promised"));
|
|
72
|
-
*
|
|
73
|
-
* @example
|
|
74
|
-
* // Write a function that supports both callbacks and Promises.
|
|
75
|
-
* const promises = require("@util.js/promises");
|
|
76
|
-
* function notify(message, who, callback) {
|
|
77
|
-
* if (!callback) return promises.applyCallback(null, notify, arguments);
|
|
78
|
-
* callback(null, `${message}, ${who}!`);
|
|
79
|
-
* }
|
|
80
|
-
* notify("Call back", "Hypnotoad", (error, message) => console.log(message));
|
|
81
|
-
* notify("Promise me", "Hypnotoad").then(console.log);
|
|
82
|
-
*
|
|
83
|
-
* @param {Object} object Value to use as this when executing functionOnObjectWithCallback (can be null)
|
|
84
|
-
* @param {Function} functionOnObjectWithCallback A function that takes a callback as its last argument
|
|
85
|
-
* @param args An array-like object containing the arguments to pass to functionOnObjectWithCallback; this is usually just [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments}
|
|
86
|
-
* @return {undefined|Promise} undefined if the last element of args is a callback or a Promise if args does not contain a callback
|
|
87
|
-
* @throws {TypeError} If functionOnObjectWithCallback is not a function or if args is null or undefined
|
|
88
|
-
* @public
|
|
89
|
-
* @instance
|
|
90
|
-
* @function
|
|
91
|
-
*/
|
|
92
|
-
applyCallback(object, functionOnObjectWithCallback, args) {
|
|
93
|
-
if (hasCallback(args))
|
|
94
|
-
return functionOnObjectWithCallback.apply(object, args);
|
|
95
|
-
return this.promisify(functionOnObjectWithCallback).apply(object, args);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Calls the given promiseFunctionOnObject with the given args that either (A) returns a Promise if args does not contain a callback or (B) notifies the callback if args contains a callback.
|
|
100
|
-
*
|
|
101
|
-
* Use this function if you are wrapping an existing function that only returns a Promise but would like that function to handle both callbacks and Promises.
|
|
102
|
-
*
|
|
103
|
-
* It is also useful in writing new functions where you would like to support both callbacks and Promises.
|
|
104
|
-
*
|
|
105
|
-
* This function adapts functions that return a Promise. {@link Promises#applyCallback} adapts functions that accept a callback.
|
|
106
|
-
*
|
|
107
|
-
* This function is similar to Function#apply. It accepts a single array of arguments.
|
|
108
|
-
*
|
|
109
|
-
* Function#call and {@link Promises#callPromise} accept an argument list.
|
|
110
|
-
*
|
|
111
|
-
* When trying to remember the difference between #apply and #call, think, "#apply accepts an array. Both array and #apply start with a."
|
|
112
|
-
*
|
|
113
|
-
* @example
|
|
114
|
-
* // Wrap a function that only returns a Promise.
|
|
115
|
-
* const promises = require("@util.js/promises");
|
|
116
|
-
* function notifyPromise(message, who) {
|
|
117
|
-
* return promises.resolve(`${message}, ${who}!`);
|
|
118
|
-
* }
|
|
119
|
-
* // #notifyPromise only returns a Promise.
|
|
120
|
-
* // Wrap #notifyPromise so that it handles both callbacks and Promises.
|
|
121
|
-
* function notify(message, who, callback) {
|
|
122
|
-
* return promises.applyPromise(null, notifyPromise, arguments);
|
|
123
|
-
* }
|
|
124
|
-
* notify("Call back", "Hypnotoad", (error, message) => console.log(message));
|
|
125
|
-
* notify("Promise me", "Hypnotoad").then(console.log);
|
|
126
|
-
*
|
|
127
|
-
* @example
|
|
128
|
-
* // Write a function that supports both callbacks and Promises.
|
|
129
|
-
* const promises = require("@util.js/promises");
|
|
130
|
-
* function notify(message, who, callback) {
|
|
131
|
-
* if (callback) return promises.applyPromise(null, notify, arguments);
|
|
132
|
-
* return promises.resolve(`${message}, ${who}!`);
|
|
133
|
-
* }
|
|
134
|
-
* notify("Call back", "Hypnotoad", (error, message) => console.log(message));
|
|
135
|
-
* notify("Promise me", "Hypnotoad").then(console.log);
|
|
136
|
-
*
|
|
137
|
-
* @param {Object} object Value to use as this when executing promiseFunctionOnObject (can be null)
|
|
138
|
-
* @param {Function} promiseFunctionOnObject A function that returns a Promise
|
|
139
|
-
* @param args An array-like object containing the arguments to pass to promiseFunctionOnObject; this is usually just [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments}
|
|
140
|
-
* @return {undefined|Promise} undefined if the last element of args is a callback or a Promise if args does not contain a callback
|
|
141
|
-
* @throws {TypeError} If promiseFunctionOnObject is not a function or if args is null or undefined
|
|
142
|
-
* @public
|
|
143
|
-
* @instance
|
|
144
|
-
* @function
|
|
145
|
-
*/
|
|
146
|
-
applyPromise(object, promiseFunctionOnObject, args) {
|
|
147
|
-
if (hasCallback(args))
|
|
148
|
-
return this.callbackify(promiseFunctionOnObject).apply(object, args);
|
|
149
|
-
return promiseFunctionOnObject.apply(object, args);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Wraps the given promiseFunction such that calling the returned function with a callback notifies the callback with an error if promiseFunction rejects or the return value if promiseFunction resolves.
|
|
154
|
-
*
|
|
155
|
-
* Use {@link Promises#callPromise} if you would like to callbackify a method and call it in one line.
|
|
156
|
-
*
|
|
157
|
-
* @example
|
|
158
|
-
* const promises = require("@util.js/promises");
|
|
159
|
-
* function notifyPromise(message, who) {
|
|
160
|
-
* return promises.resolve(`${message}, ${who}!`);
|
|
161
|
-
* }
|
|
162
|
-
* // #notifyPromise only returns a Promise.
|
|
163
|
-
* // Wrap #notifyPromise so that it accepts a callback.
|
|
164
|
-
* const notify = promises.callbackify(notifyPromise);
|
|
165
|
-
* notify("Call back", "Hypnotoad", (error, message) => console.log(message));
|
|
166
|
-
*
|
|
167
|
-
* @param {Function} promiseFunction A function that returns a Promise
|
|
168
|
-
* @return {Function} A function that accepts a callback
|
|
169
|
-
* @throws {TypeError} If promiseFunction is not a function
|
|
170
|
-
* @public
|
|
171
|
-
* @instance
|
|
172
|
-
* @function
|
|
173
|
-
*/
|
|
174
|
-
callbackify(promiseFunction) {
|
|
175
|
-
let returnValue = callbackifyCache().get(promiseFunction);
|
|
176
|
-
if (returnValue) return returnValue;
|
|
177
|
-
if (typeof promiseFunction !== "function")
|
|
178
|
-
throw new TypeError(
|
|
179
|
-
`We expected promiseFunction to be function, but it was ${promiseFunction}.`,
|
|
180
|
-
);
|
|
181
|
-
returnValue = function (...args) {
|
|
182
|
-
const callback = arguments[args.length - 1];
|
|
183
|
-
if (typeof callback !== "function")
|
|
184
|
-
throw new TypeError(
|
|
185
|
-
`We expected callback to be a function, but it was ${callback}.`,
|
|
186
|
-
);
|
|
187
|
-
const argsWithoutCalback = Array.from(args).slice(0, args.length - 1);
|
|
188
|
-
let promise;
|
|
189
|
-
try {
|
|
190
|
-
promise = promiseFunction.apply(this, argsWithoutCalback);
|
|
191
|
-
} catch (error) {
|
|
192
|
-
return callback(error);
|
|
193
|
-
}
|
|
194
|
-
if (!promise && !promise.then)
|
|
195
|
-
throw new Error(
|
|
196
|
-
`We expected promiseFunction to return a Promise but instead got ${promise}.`,
|
|
197
|
-
);
|
|
198
|
-
promise.then((result) => callback(null, result)).catch(callback);
|
|
199
|
-
// It is possible for the callback to throw an error.
|
|
200
|
-
// This should be caught by
|
|
201
|
-
// process.on('unhandledRejection', error => { ... });
|
|
202
|
-
};
|
|
203
|
-
callbackifyCache().set(promiseFunction, returnValue);
|
|
204
|
-
return returnValue;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Calls the given functionOnObjectWithCallback with the given args that either (A) returns a Promise if args does not contain a callback or (B) notifies the callback if args contains a callback.
|
|
209
|
-
*
|
|
210
|
-
* This method just calls:
|
|
211
|
-
* <pre><code>
|
|
212
|
-
* this.applyCallback(object, functionOnObjectWithCallback, args)
|
|
213
|
-
* </code></pre>
|
|
214
|
-
*
|
|
215
|
-
* See {@link Promises#applyCallback}.
|
|
216
|
-
*
|
|
217
|
-
* @example
|
|
218
|
-
* const promises = require("@util.js/promises");
|
|
219
|
-
* function notifyCallback(message, who, callback) {
|
|
220
|
-
* callback(null, `${message}, ${who}!`);
|
|
221
|
-
* }
|
|
222
|
-
* // #notifyCallback only accpets a callback.
|
|
223
|
-
* // Force #notifyCallback to return a Promise.
|
|
224
|
-
* promises
|
|
225
|
-
* .callCallback(null, notifyCallback, "Promise me", "Hypnotoad")
|
|
226
|
-
* .then(console.log);
|
|
227
|
-
*
|
|
228
|
-
* @param {Object} object Value to use as this when executing functionOnObjectWithCallback (can be null)
|
|
229
|
-
* @param {Function} functionOnObjectWithCallback A function that takes a callback as its last argument
|
|
230
|
-
* @param {...*} [args] The arguments to pass to functionOnObjectWithCallback or its promisified version
|
|
231
|
-
* @return {undefined|Promise} undefined if the last element of args is a callback or a Promise if args does not contain a callback
|
|
232
|
-
* @throws {TypeError} If functionOnObjectWithCallback is not a function
|
|
233
|
-
* @public
|
|
234
|
-
* @instance
|
|
235
|
-
* @function
|
|
236
|
-
*/
|
|
237
|
-
callCallback(object, functionOnObjectWithCallback, ...args) {
|
|
238
|
-
return this.applyCallback(object, functionOnObjectWithCallback, args);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Calls the given promiseFunctionOnObject with the given args that either (A) returns a Promise if args does not contain a callback or (B) notifies the callback if args contains a callback.
|
|
243
|
-
*
|
|
244
|
-
* This method just calls:
|
|
245
|
-
* <pre><code>
|
|
246
|
-
* this.applyCallback(object, functionOnObjectWithCallback, args)
|
|
247
|
-
* </code></pre>
|
|
248
|
-
*
|
|
249
|
-
* See {@link Promises#applyPromise}.
|
|
250
|
-
*
|
|
251
|
-
* @example
|
|
252
|
-
* const promises = require("@util.js/promises");
|
|
253
|
-
* function notifyPromise(message, who) {
|
|
254
|
-
* return promises.resolve(`${message}, ${who}!`);
|
|
255
|
-
* }
|
|
256
|
-
* // #notifyPromise only returns a Promise.
|
|
257
|
-
* // Force #notifyPromise to accept a callback.
|
|
258
|
-
* promises.callPromise(
|
|
259
|
-
* null,
|
|
260
|
-
* notifyPromise,
|
|
261
|
-
* "Call back",
|
|
262
|
-
* "Hypnotoad",
|
|
263
|
-
* (error, message) => console.log(message)
|
|
264
|
-
* );
|
|
265
|
-
*
|
|
266
|
-
* @param {Object} object Value to use as this when executing promiseFunctionOnObject (can be null)
|
|
267
|
-
* @param {Function} promiseFunctionOnObject A function that returns a Promise
|
|
268
|
-
* @param {...*} [args] The arguments to pass to promiseFunctionOnObject or its callbackified version
|
|
269
|
-
* @return {undefined|Promise} undefined if the last element of args is a callback or a Promise if args does not contain a callback
|
|
270
|
-
* @throws {TypeError} If promiseFunctionOnObject is not a function
|
|
271
|
-
* @public
|
|
272
|
-
* @instance
|
|
273
|
-
* @function
|
|
274
|
-
*/
|
|
275
|
-
callPromise(object, promiseFunctionOnObject, ...args) {
|
|
276
|
-
return this.applyPromise(object, promiseFunctionOnObject, args);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Wraps the given functionWithCallback such that calling the returned function returns a Promise that resolves if functionWithCallback succeeds and rejects if functionWithCallback errors.
|
|
281
|
-
*
|
|
282
|
-
* Use {@link Promises#callCallback} if you would like to promisify a method and call it in one line.
|
|
283
|
-
*
|
|
284
|
-
* @example
|
|
285
|
-
* const promises = require("@util.js/promises");
|
|
286
|
-
* const stream = require("stream");
|
|
287
|
-
* const streams = require("@util.js/node-streams");
|
|
288
|
-
* // stream#finished only takes a callback.
|
|
289
|
-
* // Let us wrap stream#finished so that it returns a Promise.
|
|
290
|
-
* const readable = streams.fromString("Promise me, Hypnotoad!");
|
|
291
|
-
* const finished = promises.promisify(stream.finished);
|
|
292
|
-
* finished(readable).then(() => console.log("Finished as promised"));
|
|
293
|
-
*
|
|
294
|
-
* @param {Function} functionWithCallback A function that takes a callback as its last argument
|
|
295
|
-
* @return {Function} A function that returns a Promise
|
|
296
|
-
* @throws {TypeError} If functionWithCallback is not a function
|
|
297
|
-
* @public
|
|
298
|
-
* @instance
|
|
299
|
-
* @function
|
|
300
|
-
*/
|
|
301
|
-
promisify(functionWithCallback) {
|
|
302
|
-
let returnValue = promisifyCache().get(functionWithCallback);
|
|
303
|
-
if (returnValue) return returnValue;
|
|
304
|
-
if (typeof functionWithCallback !== "function")
|
|
305
|
-
throw new TypeError(
|
|
306
|
-
`We expected functionWithCallback to be a function, but it was ${functionWithCallback}.`,
|
|
307
|
-
);
|
|
308
|
-
returnValue = function (...args) {
|
|
309
|
-
const thiz = this;
|
|
310
|
-
return new Promise((resolve, reject) => {
|
|
311
|
-
try {
|
|
312
|
-
functionWithCallback.call(thiz, ...args, function (error, ...values) {
|
|
313
|
-
if (error) return reject(error);
|
|
314
|
-
if (values.length === 0) return resolve();
|
|
315
|
-
if (values.length === 1) return resolve(values[0]);
|
|
316
|
-
resolve(values);
|
|
317
|
-
});
|
|
318
|
-
} catch (err) {
|
|
319
|
-
reject(err);
|
|
320
|
-
}
|
|
321
|
-
});
|
|
322
|
-
};
|
|
323
|
-
promisifyCache().set(functionWithCallback, returnValue);
|
|
324
|
-
return returnValue;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
/**
|
|
328
|
-
* Returns a promise that resolves or rejects as soon as one of the promises in the iterable resolves or rejects, with the value or reason from that promise.
|
|
329
|
-
*
|
|
330
|
-
* See MDN's documentation about [race]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race}.
|
|
331
|
-
*
|
|
332
|
-
* There is one minor difference between Promise#race and this method. Promise#race only takes one argument that must be iterable. This method, Promises#race, behaves the same as Promise#race when given one argument; when given multiple arguments, [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments} becomes the iterable.
|
|
333
|
-
*
|
|
334
|
-
* @example
|
|
335
|
-
* const promises = require("@util.js/promises");
|
|
336
|
-
* const promise1 = new Promise((resolve, reject) => {
|
|
337
|
-
* setTimeout(resolve, 500, "one");
|
|
338
|
-
* });
|
|
339
|
-
* const promise2 = new Promise((resolve, reject) => {
|
|
340
|
-
* setTimeout(resolve, 100, "two");
|
|
341
|
-
* });
|
|
342
|
-
* promises.race(promise1, promise2).then(value => {
|
|
343
|
-
* console.log(value);
|
|
344
|
-
* // Both resolve, but promise2 is faster
|
|
345
|
-
* });
|
|
346
|
-
* // expected output: "two"
|
|
347
|
-
*
|
|
348
|
-
* @param {iterable|...*} iterable An iterable object such as an Array or String; if you give move than one argument to this method, [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments} becomes the iterable
|
|
349
|
-
* @return {Promise} A pending Promise that resolves or rejects asynchronically (as soon as the stack is empty) as soon as one of the promises in the given iterable resolves or rejects, adopting that first promise's value as its value
|
|
350
|
-
* @public
|
|
351
|
-
* @instance
|
|
352
|
-
* @function
|
|
353
|
-
*/
|
|
354
|
-
race() {
|
|
355
|
-
if (arguments.length > 1) return Promise.race(arguments);
|
|
356
|
-
return Promise.race(...arguments);
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* Returns a Promise object that is rejected with the given reason.
|
|
361
|
-
*
|
|
362
|
-
* See MDN's documentation about [reject]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject}.
|
|
363
|
-
*
|
|
364
|
-
* @param {*} reason Reason why this Promise rejected
|
|
365
|
-
* @return {Promise} A Promise that is rejected with the given reason
|
|
366
|
-
* @public
|
|
367
|
-
* @instance
|
|
368
|
-
* @function
|
|
369
|
-
*/
|
|
370
|
-
reject() {
|
|
371
|
-
// eslint-disable-next-line prefer-promise-reject-errors
|
|
372
|
-
return Promise.reject(...arguments);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* Returns a Promise object that is resolved with the given value.
|
|
377
|
-
*
|
|
378
|
-
* If the value is a promise, that promise is returned; if the value is a thenable (i.e. has a "then" method), the returned promise will "follow" that thenable, adopting its eventual state; otherwise the returned promise will be fulfilled with the value.
|
|
379
|
-
*
|
|
380
|
-
* See MDN's documentation about [resolve]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve}.
|
|
381
|
-
*
|
|
382
|
-
* @param {*} value Argument to be resolved by this Promise that can also be a Promise or a thenable to resolve
|
|
383
|
-
* @return {Promise} A Promise that is resolved with the given value, or the promise passed as value, if the value was a promise object
|
|
384
|
-
* @public
|
|
385
|
-
* @instance
|
|
386
|
-
* @function
|
|
387
|
-
*/
|
|
388
|
-
resolve() {
|
|
389
|
-
return Promise.resolve(...arguments);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
module.exports = Promises;
|
|
394
|
-
|
|
395
|
-
const dependencies = {};
|
|
396
|
-
|
|
397
|
-
function callbackifyCache() {
|
|
398
|
-
return (
|
|
399
|
-
dependencies.callbackifyCache ||
|
|
400
|
-
(dependencies.callbackifyCache = new WeakMap())
|
|
401
|
-
);
|
|
402
|
-
}
|
|
403
|
-
function promisifyCache() {
|
|
404
|
-
return (
|
|
405
|
-
dependencies.promisifyCache || (dependencies.promisifyCache = new WeakMap())
|
|
406
|
-
);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
function hasCallback(args) {
|
|
410
|
-
return args.length > 0 && typeof args[args.length - 1] === "function";
|
|
411
|
-
}
|
package/test/PromisesTest.js
DELETED
|
@@ -1,477 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const { expect } = require("chai");
|
|
4
|
-
const promises = require("..");
|
|
5
|
-
|
|
6
|
-
describe("Promises", function () {
|
|
7
|
-
describe("#(apply|call)Callback(object, functionOnObjectWithCallback, args)", () => {
|
|
8
|
-
function notify(message, who, callback) {
|
|
9
|
-
if (message === "Throw error") throw new Error("Hypnotoad died.");
|
|
10
|
-
if (message === "Return undefined") return;
|
|
11
|
-
callback(null, `${message}, ${who}!`);
|
|
12
|
-
}
|
|
13
|
-
it("should resolve a Promise", async function () {
|
|
14
|
-
expect(
|
|
15
|
-
await promises.applyCallback(null, notify, ["Promise me", "Hypnotoad"]),
|
|
16
|
-
).to.eql("Promise me, Hypnotoad!");
|
|
17
|
-
expect(
|
|
18
|
-
await promises.callCallback(null, notify, "Promise me", "Hypnotoad"),
|
|
19
|
-
).to.eql("Promise me, Hypnotoad!");
|
|
20
|
-
});
|
|
21
|
-
it("should error if functionOnObjectWithCallback is not a function", () => {
|
|
22
|
-
expect(() =>
|
|
23
|
-
promises.applyCallback(null, null, ["Promise me", "Hypnotoad"]),
|
|
24
|
-
).to.throw(TypeError);
|
|
25
|
-
expect(() =>
|
|
26
|
-
promises.callCallback(null, null, "Promise me", "Hypnotoad"),
|
|
27
|
-
).to.throw(TypeError);
|
|
28
|
-
expect(() =>
|
|
29
|
-
promises.applyCallback(null, "a", ["Promise me", "Hypnotoad"]),
|
|
30
|
-
).to.throw(TypeError);
|
|
31
|
-
expect(() =>
|
|
32
|
-
promises.callCallback(null, "a", "Promise me", "Hypnotoad"),
|
|
33
|
-
).to.throw(TypeError);
|
|
34
|
-
});
|
|
35
|
-
it("should error if args is erroneous", () => {
|
|
36
|
-
// This does not cause failures in the unit test, but there is output.
|
|
37
|
-
promises
|
|
38
|
-
.callCallback(null, notify, "Return undefined")
|
|
39
|
-
.then((message) => {
|
|
40
|
-
throw new Error("Expected expected the function to never return.");
|
|
41
|
-
})
|
|
42
|
-
.catch((error) => {
|
|
43
|
-
throw error;
|
|
44
|
-
});
|
|
45
|
-
expect(() => promises.applyCallback(null, notify)).to.throw(TypeError);
|
|
46
|
-
const a = promises
|
|
47
|
-
.callCallback(null, notify)
|
|
48
|
-
.catch((error) => expect(error).to.be.an.instanceof(TypeError));
|
|
49
|
-
const b = promises
|
|
50
|
-
.applyCallback(null, notify, ["Hypnotoad"])
|
|
51
|
-
.catch((error) => expect(error).to.be.an.instanceof(TypeError));
|
|
52
|
-
const c = promises
|
|
53
|
-
.callCallback(null, notify, "Hypnotoad")
|
|
54
|
-
.catch((error) => expect(error).to.be.an.instanceof(TypeError));
|
|
55
|
-
const d = promises
|
|
56
|
-
.applyCallback(null, notify, ["Throw error"])
|
|
57
|
-
.catch((error) => expect(error).to.be.an.instanceof(Error));
|
|
58
|
-
const e = promises
|
|
59
|
-
.callCallback(null, notify, "Throw error")
|
|
60
|
-
.catch((error) => expect(error).to.be.an.instanceof(Error));
|
|
61
|
-
return promises.all(a, b, c, d, e);
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
describe("#(apply|call)Promise(object, promiseFunctionOnObject, args)", () => {
|
|
66
|
-
function notify(message, who) {
|
|
67
|
-
if (message === "Throw error") throw new Error("Hypnotoad died.");
|
|
68
|
-
if (message === "Return undefined") return;
|
|
69
|
-
return promises.resolve(`${message}, ${who}!`);
|
|
70
|
-
}
|
|
71
|
-
it("should notify a callback", (callback) => {
|
|
72
|
-
a(callback);
|
|
73
|
-
function a(callbck) {
|
|
74
|
-
promises.applyPromise(null, notify, [
|
|
75
|
-
"Call back",
|
|
76
|
-
"Hypnotoad",
|
|
77
|
-
(error, message) => {
|
|
78
|
-
if (error) {
|
|
79
|
-
callbck(error);
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
expect(message).to.eql("Call back, Hypnotoad!");
|
|
83
|
-
b(callbck);
|
|
84
|
-
},
|
|
85
|
-
]);
|
|
86
|
-
}
|
|
87
|
-
function b(callbck) {
|
|
88
|
-
promises.callPromise(
|
|
89
|
-
null,
|
|
90
|
-
notify,
|
|
91
|
-
"Call back",
|
|
92
|
-
"Hypnotoad",
|
|
93
|
-
(error, message) => {
|
|
94
|
-
if (error) {
|
|
95
|
-
callbck(error);
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
expect(message).to.eql("Call back, Hypnotoad!");
|
|
99
|
-
c(callbck);
|
|
100
|
-
},
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
function c(callbck) {
|
|
104
|
-
function adapt(message, who, callback) {
|
|
105
|
-
if (callback) return promises.applyPromise(null, notify, arguments);
|
|
106
|
-
return promises.resolve(`${message}, ${who}!`);
|
|
107
|
-
}
|
|
108
|
-
promises.callPromise(
|
|
109
|
-
null,
|
|
110
|
-
adapt,
|
|
111
|
-
"Call back",
|
|
112
|
-
"Hypnotoad",
|
|
113
|
-
(error, value) => {
|
|
114
|
-
if (error) {
|
|
115
|
-
callbck(error);
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
try {
|
|
119
|
-
expect(value).to.eql("Call back, Hypnotoad!");
|
|
120
|
-
callbck();
|
|
121
|
-
} catch (err) {
|
|
122
|
-
callbck(err);
|
|
123
|
-
}
|
|
124
|
-
},
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
it("should error if promiseFunction is not a function", () => {
|
|
129
|
-
expect(() =>
|
|
130
|
-
promises.applyPromise(null, null, ["Call back", "Hypnotoad"]),
|
|
131
|
-
).to.throw(TypeError);
|
|
132
|
-
expect(() =>
|
|
133
|
-
promises.callPromise(null, null, "Call back", "Hypnotoad"),
|
|
134
|
-
).to.throw(TypeError);
|
|
135
|
-
expect(() =>
|
|
136
|
-
promises.applyPromise(null, "a", ["Call back", "Hypnotoad"]),
|
|
137
|
-
).to.throw(TypeError);
|
|
138
|
-
expect(() =>
|
|
139
|
-
promises.callPromise(null, "a", "Call back", "Hypnotoad"),
|
|
140
|
-
).to.throw(TypeError);
|
|
141
|
-
});
|
|
142
|
-
it("should handle erroneous input", (callback) => {
|
|
143
|
-
a(callback);
|
|
144
|
-
function a(callbck) {
|
|
145
|
-
try {
|
|
146
|
-
expect(() => promises.applyPromise(null, notify)).to.throw(TypeError);
|
|
147
|
-
b(callbck);
|
|
148
|
-
} catch (error) {
|
|
149
|
-
callbck(error);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
function b(callbck) {
|
|
153
|
-
promises
|
|
154
|
-
.callPromise(null, notify)
|
|
155
|
-
.then((message) => {
|
|
156
|
-
expect(message).to.eql("undefined, undefined!");
|
|
157
|
-
c(callbck);
|
|
158
|
-
})
|
|
159
|
-
.catch(callbck);
|
|
160
|
-
}
|
|
161
|
-
function c(callbck) {
|
|
162
|
-
promises.applyPromise(null, notify, [
|
|
163
|
-
"Call back",
|
|
164
|
-
(error, value) => {
|
|
165
|
-
try {
|
|
166
|
-
expect(error).to.be.null;
|
|
167
|
-
expect(value).to.eql("Call back, undefined!");
|
|
168
|
-
d(callbck);
|
|
169
|
-
} catch (err) {
|
|
170
|
-
callbck(err);
|
|
171
|
-
}
|
|
172
|
-
},
|
|
173
|
-
]);
|
|
174
|
-
}
|
|
175
|
-
function d(callbck) {
|
|
176
|
-
promises.callPromise(null, notify, "Call back", (error, value) => {
|
|
177
|
-
try {
|
|
178
|
-
expect(error).to.be.null;
|
|
179
|
-
expect(value).to.eql("Call back, undefined!");
|
|
180
|
-
e(callbck);
|
|
181
|
-
} catch (err) {
|
|
182
|
-
callbck(err);
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
function e(callbck) {
|
|
187
|
-
promises.applyPromise(null, notify, [
|
|
188
|
-
"Throw error",
|
|
189
|
-
(error, value) => {
|
|
190
|
-
try {
|
|
191
|
-
expect(error).to.be.an.instanceof(Error);
|
|
192
|
-
expect(value).to.be.undefined;
|
|
193
|
-
f(callbck);
|
|
194
|
-
} catch (err) {
|
|
195
|
-
callbck(err);
|
|
196
|
-
}
|
|
197
|
-
},
|
|
198
|
-
]);
|
|
199
|
-
}
|
|
200
|
-
function f(callbck) {
|
|
201
|
-
promises.callPromise(null, notify, "Throw error", (error, value) => {
|
|
202
|
-
try {
|
|
203
|
-
expect(error).to.be.an.instanceof(Error);
|
|
204
|
-
expect(value).to.be.undefined;
|
|
205
|
-
g(callbck);
|
|
206
|
-
} catch (err) {
|
|
207
|
-
callbck(err);
|
|
208
|
-
}
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
function g(callbck) {
|
|
212
|
-
try {
|
|
213
|
-
expect(() =>
|
|
214
|
-
promises.callPromise(
|
|
215
|
-
null,
|
|
216
|
-
notify,
|
|
217
|
-
"Return undefined",
|
|
218
|
-
(error, value) => {
|
|
219
|
-
callback(
|
|
220
|
-
new Error(
|
|
221
|
-
"We expected #callPromise to not call this callback.",
|
|
222
|
-
{ cause: error },
|
|
223
|
-
),
|
|
224
|
-
);
|
|
225
|
-
},
|
|
226
|
-
),
|
|
227
|
-
).to.throw(Error);
|
|
228
|
-
callbck();
|
|
229
|
-
} catch (error) {
|
|
230
|
-
callbck(error);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
describe("#all(iterable)", () => {
|
|
237
|
-
it("should properly handle a single, iterable argument", () => {
|
|
238
|
-
const promise1 = Promise.resolve(3);
|
|
239
|
-
const promise2 = 42;
|
|
240
|
-
const promise3 = new Promise((resolve, reject) => {
|
|
241
|
-
setTimeout(resolve, 100, "foo");
|
|
242
|
-
});
|
|
243
|
-
return promises.all([promise1, promise2, promise3]).then((values) => {
|
|
244
|
-
expect(values).to.eql([3, 42, "foo"]);
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
it("should properly handle a single, iterable argument", () => {
|
|
248
|
-
const promise1 = Promise.resolve(3);
|
|
249
|
-
const promise2 = 42;
|
|
250
|
-
const promise3 = new Promise((resolve, reject) => {
|
|
251
|
-
setTimeout(resolve, 100, "foo");
|
|
252
|
-
});
|
|
253
|
-
return promises.all(promise1, promise2, promise3).then((values) => {
|
|
254
|
-
expect(values).to.eql([3, 42, "foo"]);
|
|
255
|
-
});
|
|
256
|
-
});
|
|
257
|
-
it("should reject when given no arguments", () => {
|
|
258
|
-
return promises
|
|
259
|
-
.all()
|
|
260
|
-
.then(() => expect.fail("We expected promises#all to fail."))
|
|
261
|
-
.catch((error) => expect(error).to.be.an.instanceof(TypeError));
|
|
262
|
-
});
|
|
263
|
-
it("should resolve with [] when given [] as an argument", () => {
|
|
264
|
-
return promises.all([]).then((values) => {
|
|
265
|
-
expect(values).to.eql([]);
|
|
266
|
-
});
|
|
267
|
-
});
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
describe("#applyCallback(object, functionOnObjectWithCallback, args)", () => {
|
|
271
|
-
it("should call the callback if args contains a callback", (callback) => {
|
|
272
|
-
function functionWithCallback(a, b, cb) {
|
|
273
|
-
expect(a).to.eql("a");
|
|
274
|
-
expect(b).to.eql("b");
|
|
275
|
-
cb();
|
|
276
|
-
}
|
|
277
|
-
const returnValue = promises.applyCallback(null, functionWithCallback, [
|
|
278
|
-
"a",
|
|
279
|
-
"b",
|
|
280
|
-
callback,
|
|
281
|
-
]);
|
|
282
|
-
try {
|
|
283
|
-
expect(returnValue).to.be.undefined;
|
|
284
|
-
} catch (e) {
|
|
285
|
-
callback(e);
|
|
286
|
-
}
|
|
287
|
-
});
|
|
288
|
-
it("should resolve the returned Promise if args does not contain a callback", () => {
|
|
289
|
-
function functionWithCallback(a, b, cb) {
|
|
290
|
-
expect(a).to.eql("a");
|
|
291
|
-
expect(b).to.eql("b");
|
|
292
|
-
cb();
|
|
293
|
-
}
|
|
294
|
-
return promises.applyCallback(null, functionWithCallback, ["a", "b"]);
|
|
295
|
-
});
|
|
296
|
-
it("should throw an Error if functionWithCallback or args is null or undefined", () => {
|
|
297
|
-
function functionWithCallback(cb) {
|
|
298
|
-
cb();
|
|
299
|
-
}
|
|
300
|
-
expect(() => promises.applyCallback(null, functionWithCallback)).to.throw(
|
|
301
|
-
TypeError,
|
|
302
|
-
);
|
|
303
|
-
expect(() =>
|
|
304
|
-
promises.applyCallback(null, functionWithCallback, null),
|
|
305
|
-
).to.throw(TypeError);
|
|
306
|
-
// The following line sends functionWithCallback the wrong number of arguments.
|
|
307
|
-
expect(() =>
|
|
308
|
-
promises.applyCallback(null, functionWithCallback, "a"),
|
|
309
|
-
).to.throw(TypeError);
|
|
310
|
-
expect(() => promises.applyCallback(null, null, [() => {}])).to.throw(
|
|
311
|
-
TypeError,
|
|
312
|
-
);
|
|
313
|
-
expect(() => promises.applyCallback(null, "a", [() => {}])).to.throw(
|
|
314
|
-
TypeError,
|
|
315
|
-
);
|
|
316
|
-
expect(() => promises.applyCallback(null, null, [])).to.throw(TypeError);
|
|
317
|
-
expect(() => promises.applyCallback(null, "a", [])).to.throw(TypeError);
|
|
318
|
-
});
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
describe("#callbackify(promiseFunction)", () => {
|
|
322
|
-
it("should callbackify Promise functions with no arguments", (callback) => {
|
|
323
|
-
function promiseFunction() {
|
|
324
|
-
return Promise.resolve("foobar");
|
|
325
|
-
}
|
|
326
|
-
promises.callbackify(promiseFunction)((error, value) => {
|
|
327
|
-
try {
|
|
328
|
-
expect(error).to.be.null;
|
|
329
|
-
expect(value).to.eql("foobar");
|
|
330
|
-
callback();
|
|
331
|
-
} catch (err) {
|
|
332
|
-
callback(err);
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
});
|
|
336
|
-
it("should callbackify Promise functions with one arguments", (callback) => {
|
|
337
|
-
function promiseFunction(message) {
|
|
338
|
-
return Promise.resolve(message);
|
|
339
|
-
}
|
|
340
|
-
promises.callbackify(promiseFunction)("foobar", (error, value) => {
|
|
341
|
-
try {
|
|
342
|
-
expect(error).to.be.null;
|
|
343
|
-
expect(value).to.eql("foobar");
|
|
344
|
-
callback();
|
|
345
|
-
} catch (err) {
|
|
346
|
-
callback(err);
|
|
347
|
-
}
|
|
348
|
-
});
|
|
349
|
-
});
|
|
350
|
-
it("should callbackify Promise functions with two arguments", (callback) => {
|
|
351
|
-
function promiseFunction(a, b) {
|
|
352
|
-
return Promise.resolve(a + b);
|
|
353
|
-
}
|
|
354
|
-
promises.callbackify(promiseFunction)("foo", "bar", (error, value) => {
|
|
355
|
-
try {
|
|
356
|
-
expect(error).to.be.null;
|
|
357
|
-
expect(value).to.eql("foobar");
|
|
358
|
-
callback();
|
|
359
|
-
} catch (err) {
|
|
360
|
-
callback(err);
|
|
361
|
-
}
|
|
362
|
-
});
|
|
363
|
-
});
|
|
364
|
-
it("should cache callbackified functions", () => {
|
|
365
|
-
function promiseFunction(a, b) {
|
|
366
|
-
return Promise.resolve(a + b);
|
|
367
|
-
}
|
|
368
|
-
const a = promises.callbackify(promiseFunction);
|
|
369
|
-
const b = promises.callbackify(promiseFunction);
|
|
370
|
-
expect(a === b).to.be.ok;
|
|
371
|
-
});
|
|
372
|
-
it("should throw an error if promiseFunction is not a function", () => {
|
|
373
|
-
expect(() => promises.callbackify()).to.throw(TypeError);
|
|
374
|
-
expect(() => promises.callbackify(null)).to.throw(TypeError);
|
|
375
|
-
expect(() => promises.callbackify("a")).to.throw(TypeError);
|
|
376
|
-
});
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
describe("#promisify(functionWithCallback)", () => {
|
|
380
|
-
it("should promisify callback functions with one argument", () => {
|
|
381
|
-
function functionWithCallback(callback) {
|
|
382
|
-
callback();
|
|
383
|
-
}
|
|
384
|
-
return promises.promisify(functionWithCallback)();
|
|
385
|
-
});
|
|
386
|
-
it("should promisify callback functions with two arguments", () => {
|
|
387
|
-
function functionWithCallback(a, callback) {
|
|
388
|
-
expect(a).to.eql("a");
|
|
389
|
-
callback();
|
|
390
|
-
}
|
|
391
|
-
return promises.promisify(functionWithCallback)("a");
|
|
392
|
-
});
|
|
393
|
-
it("should promisify callback functions with three arguments", () => {
|
|
394
|
-
function functionWithCallback(a, b, callback) {
|
|
395
|
-
expect(a).to.eql("a");
|
|
396
|
-
expect(b).to.eql("b");
|
|
397
|
-
callback();
|
|
398
|
-
}
|
|
399
|
-
return promises.promisify(functionWithCallback)("a", "b");
|
|
400
|
-
});
|
|
401
|
-
it("should cache promisified functions", () => {
|
|
402
|
-
function functionWithCallback(a, b, callback) {
|
|
403
|
-
expect(a).to.eql("a");
|
|
404
|
-
expect(b).to.eql("b");
|
|
405
|
-
callback();
|
|
406
|
-
}
|
|
407
|
-
const a = promises.promisify(functionWithCallback);
|
|
408
|
-
const b = promises.promisify(functionWithCallback);
|
|
409
|
-
expect(a === b).to.be.ok;
|
|
410
|
-
});
|
|
411
|
-
it("should reject if functionWithCallback is not a function", () => {
|
|
412
|
-
expect(() => promises.promisify()).to.throw(TypeError);
|
|
413
|
-
expect(() => promises.promisify(null)).to.throw(TypeError);
|
|
414
|
-
expect(() => promises.promisify("random")).to.throw(TypeError);
|
|
415
|
-
});
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
describe("#callCallback", () => {
|
|
419
|
-
it("should handle functions with only a callback", () => {
|
|
420
|
-
function functionWithCallback(callback) {
|
|
421
|
-
callback();
|
|
422
|
-
}
|
|
423
|
-
return promises.callCallback(this, functionWithCallback);
|
|
424
|
-
});
|
|
425
|
-
it("should handle functions with multiple arguments", () => {
|
|
426
|
-
function functionWithCallback(x, y, z, callback) {
|
|
427
|
-
expect(x).to.equal(1);
|
|
428
|
-
expect(y).to.equal(2);
|
|
429
|
-
expect(z).to.equal(3);
|
|
430
|
-
callback(null, x + y + z);
|
|
431
|
-
}
|
|
432
|
-
return promises
|
|
433
|
-
.callCallback(this, functionWithCallback, 1, 2, 3)
|
|
434
|
-
.then((result) => {
|
|
435
|
-
expect(result).to.equal(6);
|
|
436
|
-
});
|
|
437
|
-
});
|
|
438
|
-
it("should throw an Error if functionWithCallback or args is null or undefined", () => {
|
|
439
|
-
function functionWithCallback(cb) {
|
|
440
|
-
cb();
|
|
441
|
-
}
|
|
442
|
-
// The following line sends functionWithCallback the wrong number of arguments.
|
|
443
|
-
const a = promises
|
|
444
|
-
.callCallback(null, functionWithCallback, "a")
|
|
445
|
-
.then(() => expect.fail("We expected call to throw an error."))
|
|
446
|
-
.catch((error) => expect(error).to.be.an.instanceof(TypeError));
|
|
447
|
-
expect(() => promises.callCallback(null, null)).to.throw(TypeError);
|
|
448
|
-
expect(() => promises.callCallback(null, "a")).to.throw(TypeError);
|
|
449
|
-
return a;
|
|
450
|
-
});
|
|
451
|
-
});
|
|
452
|
-
|
|
453
|
-
describe("#race(iterable)", () => {
|
|
454
|
-
it("should handle a single, iterable argument", () => {
|
|
455
|
-
const promise1 = new Promise((resolve, reject) => {
|
|
456
|
-
setTimeout(resolve, 500, "one");
|
|
457
|
-
});
|
|
458
|
-
const promise2 = new Promise((resolve, reject) => {
|
|
459
|
-
setTimeout(resolve, 100, "two");
|
|
460
|
-
});
|
|
461
|
-
return promises.race([promise1, promise2]).then((value) => {
|
|
462
|
-
expect(value).to.eql("two");
|
|
463
|
-
});
|
|
464
|
-
});
|
|
465
|
-
it("should handle multiple arguments", () => {
|
|
466
|
-
const promise1 = new Promise((resolve, reject) => {
|
|
467
|
-
setTimeout(resolve, 500, "one");
|
|
468
|
-
});
|
|
469
|
-
const promise2 = new Promise((resolve, reject) => {
|
|
470
|
-
setTimeout(resolve, 100, "two");
|
|
471
|
-
});
|
|
472
|
-
return promises.race(promise1, promise2).then((value) => {
|
|
473
|
-
expect(value).to.eql("two");
|
|
474
|
-
});
|
|
475
|
-
});
|
|
476
|
-
});
|
|
477
|
-
});
|