Skip to content

Instantly share code, notes, and snippets.

@Arlen22
Last active March 2, 2025 17:20
Show Gist options
  • Save Arlen22/3b17fc55c63354a4038f3638eecb1534 to your computer and use it in GitHub Desktop.
Save Arlen22/3b17fc55c63354a4038f3638eecb1534 to your computer and use it in GitHub Desktop.
A "polyfill" with examples for the try operator
function try_(callback, thisarg) {
class Result {
constructor(ok, error, value) {
this.ok = ok
this.error = error
this.value = value
}
*[Symbol.iterator]() {
yield this.ok
yield this.error
yield this.value
}
static ok(value) {
return new Result(true, undefined, value)
}
static error(error) {
return new Result(false, error, undefined)
}
}
const syncCall = (function () {
try {
return Result.ok(callback.apply(thisarg));
} catch (e) {
return Result.error(e);
}
})();
if (!syncCall.ok) return syncCall;
if (isPromise(syncCall.value)) {
return syncCall.value.then(
(value) => Result.ok(value),
(e) => Result.error(e)
);
}
if (isIterable(syncCall.value)) {
return (function* () {
try {
return Result.ok(yield* syncCall.value);
} catch (e) {
return Result.error(e);
}
})();
}
if (isAsyncIterable(syncCall.value)) {
return (async function* () {
try {
return Result.ok(yield* syncCall.value);
} catch (e) {
return Result.error(e);
}
})();
}
return syncCall;
function isPromise(result) { return result && typeof result.then === 'function'; }
function isIterable(result) { return result && typeof result[Symbol.iterator] === 'function'; }
function isAsyncIterable(result) { return result && typeof result[Symbol.asyncIterator] === 'function'; }
}
function* parent() {
return yield* try_(function*() {
return yield "hello"; //this yields from parent
}, this);
}
const iter = parent();
console.log(iter.next().value); // prints "hello"
const { value: [good, error, value], done } = iter.next("some value");
console.log(done, value) // prints true "some value"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment