Last active
March 2, 2025 17:20
-
-
Save Arlen22/3b17fc55c63354a4038f3638eecb1534 to your computer and use it in GitHub Desktop.
A "polyfill" with examples for the try operator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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