Simplify implementation of select.

This commit is contained in:
David Braun 2019-03-20 11:09:26 -04:00
parent ea2cc74711
commit 3ff3031b1e
No known key found for this signature in database
GPG key ID: 87EC41ADF710B7E2
2 changed files with 37 additions and 37 deletions

View file

@ -403,45 +403,45 @@ Channel.of = (...values) => Channel.from(values);
Channel.isChannel = arg =>
arg !== undefined && arg !== null && Object.getPrototypeOf(arg) === prototype;
Channel.select = methodPromises =>
Object.assign(
new Promise((resolve, reject) => {
Channel.select = methodPromises => {
if (!Array.isArray(methodPromises)) {
throw new TypeError(`Channel.select: Argument must be an array.`);
}
const selectPromise = new Promise((resolve, reject) => {
methodPromises.forEach(async promise => {
try {
methodPromises.forEach(async promise => {
try {
promise.prethen(() => {
// We've been given a heads-up that this method will complete first
// so cancel the other method calls.
methodPromises.forEach(other => {
if (other !== promise) {
other.cancel();
}
});
});
try {
await promise;
} catch (exception) {
reject(exception);
promise.prethen(() => {
// We've been given a heads-up that this method will complete first
// so cancel the other method calls.
methodPromises.forEach(other => {
if (other !== promise) {
other.cancel();
}
resolve(promise.channel);
} catch (exception) {
reject(
new TypeError(
`Channel.select accepts only promises returned by push & shift.`
)
);
}
});
});
try {
await promise;
} catch (exception) {
reject(exception);
}
resolve(promise.channel);
} catch (exception) {
reject(new TypeError(`Channel.select: Argument must be an array.`));
reject(
new TypeError(
`Channel.select accepts only promises returned by push & shift.`
)
);
}
}),
{
cancel: () => Promise.all(methodPromises.map(promise => promise.cancel()))
}
);
});
});
return Object.assign(selectPromise, {
cancel: () => methodPromises.forEach(promise => promise.cancel())
});
};
// functional interface allowing full or partial application
//

View file

@ -98,6 +98,7 @@ describe(`Channel function`, function() {
it(`miscellaneous`, async function() {
const a = Channel();
const b = Channel();
(async () => {
await b.push(0);
await a.push(1);
@ -114,10 +115,9 @@ describe(`Channel function`, function() {
it(`allows for non-blocking selects`, async function() {
const a = Channel();
const b = Channel();
const closed = Channel.of();
switch (
await Channel.select([a.shift(), b.push(0), Channel.of().shift()])
) {
switch (await Channel.select([a.shift(), b.push(0), closed.shift()])) {
case a:
assert(false);
break;