arthurfiorette / proposal-safe-assignment-operator

Draft for ECMAScript Error Safe Assignment Operator
https://arthur.run/proposal-safe-assignment-operator/
MIT License
1.45k stars 16 forks source link

async functions already allow this pattern, but only asyncly #45

Open Arlen22 opened 2 months ago

Arlen22 commented 2 months ago

Current proposed syntax is const [error, data] = try await func(); according to #4

Async functions already basically allow this pattern. An async function returns a promise, and any synchronous exception thrown causes the promise to return a rejected promise.

A call to an async function using this pattern looks like const [error, data] = await asyncFunc().then(e => [undefined, e], e => [e, undefined]);. The only advantage of turning this into an operator is that typescript can handle the typing of this properly (removing undefined from the value type if the error is undefined).

But since making every single Javascript function async doesn't really make sense, this is still a useful operator to have. In fact, it may even bring a compelling use case to the sync world.

rockedpanda commented 2 months ago

If change the Promise.prototype:

Promise.prototype.result = function() {
  return this.then(x=>[null,x], err=>[err,null]);
};

will it be better ?

const [error, data] = await asyncFunc().result();

Not for sync

otaxhu commented 1 month ago

If change the Promise.prototype:

Promise.prototype.result = function() {
  return this.then(x=>[null,x], err=>[err,null]);
};

This is actually a really good pattern, we should discuss about this in #4 (preferred operator/keyword for safe assignment)

Arlen22 commented 1 month ago

There is no need to add anything to the Promise prototype. The current try await ... expression already handles it exactly how it needs to.

Currently const result = try await somePromise would be the equivelant of the current code:

let result = new Array(2);
try {
  result[1] = await somePromise; // the expression goes here
} catch (e) {
  result[0] = e;
}

Shortening all of that down to one expression keyword and adding the const assignment is quite epic. No further polyfill is needed.

Arlen22 commented 1 month ago

In fact, I've added a try method to the Promise prototype in one of my projects.

return this.then(e => [undefined, e] as const, e => [e, undefined] as const);

ljharb commented 1 month ago

@Arlen22 please don't ever do that - that's the kind of thing that obstructs language evolution.

Arlen22 commented 1 month ago

@Arlen22 please don't ever do that - that's the kind of thing that obstructs language evolution.

No worries. I entirely agree. I am certainly not putting that online anywhere. I could accomplish the same thing with try(await something), which would be a much better solution.