Equivalent de try… catch comme expression

Aug 31 2020

Je cherche un moyen de faire quelque chose comme:

myVar = try {someFunction();} catch (e) {return undefined;} ?? defaultValue;

Ce que je sais n'est pas correct, mais vous voyez l'idée. Je me demandais simplement s'il y avait une manière élégante de faire cela?

Réponses

2 CertainPerformance Aug 31 2020 at 03:51

Le mieux que vous puissiez faire actuellement est probablement un IIFE:

myVar = (() => {
  try {
    return someFunction();
  } catch (e) {
  }
})() ?? defaultValue;
PeterSeliger Aug 31 2020 at 05:43

L'implémentation par exemple d'un modificateur de méthode pourrait aboutir à une expression aussi courte et aussi proche que le pseudo code de l'OP ...afterThrowing

const value = try {someFunction();} catch (e) {return undefined;} ?? defaultValue;

... alors se transformerait en quelque chose comme ...

const value = (someFunction.afterThrowing(() => null)()) ?? defaultValue;

... implémentation et exemple de code comme preuve de concept ...

// myVar = try {someFunction();} catch (e) {return undefined;} ?? defaultValue;

function throwError() {
  throw (new Error('invocation failure'));
}
function getDate() {
  return Date.now();
}
const defaultValue = '... did throw.'

// expressions as short and as close as one can get
// to what has been ask for ...
//
console.log(
  (getDate.afterThrowing(() => null)()) ?? defaultValue
);
console.log(
  (throwError.afterThrowing(() => null)()) ?? defaultValue
);


// demonstrate capability of the after throwing handler ...
function afterThrowingHandler(error, args) {
  console.log(
    'afterThrowingHandler :: context, error, argsList :',
    this,
    error.toString(),
    Array.from(args)
  );
  return null; // according to the OP's use case.
}

console.log(
  (getDate.afterThrowing(afterThrowingHandler)()) ?? defaultValue
);

console.log(
  (throwError.afterThrowing(

    afterThrowingHandler,
    { biz: 'buzz' }

  )('foo', 'bar', 'baz')) ?? defaultValue
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script>
  (function (Function) {

    const fctPrototype = Function.prototype;
    const FUNCTION_TYPE = (typeof Function);

    function isFunction(type) {
      return (
           (typeof type == FUNCTION_TYPE)
        && (typeof type.call == FUNCTION_TYPE)
        && (typeof type.apply == FUNCTION_TYPE)
      );
    }
    function getSanitizedTarget(target) {
      return ((target != null) && target) || null;
    }

    function afterThrowing/*Modifier*/(handler, target) {
      target = getSanitizedTarget(target);

      const proceed = this;
      return (

        isFunction(handler) &&
        isFunction(proceed) &&

        function () {
          const context = target || getSanitizedTarget(this);
          const args = arguments;

          let result;
          try {
            result = proceed.apply(context, args);

          } catch (exception) {

            result = handler.call(context, exception, args);
          }
          return result;
        }

      ) || proceed;
    }
    // afterThrowing.toString = () => 'afterThrowing() { [native code] }';

    Object.defineProperty(fctPrototype, 'afterThrowing', {
      configurable: true,
      writable: true,
      value: afterThrowing/*Modifier*/
    });

  }(Function));
</script>

Je ne me dérangerait pas si, un jour, le JavaScript officiellement ... .Function.prototype[before|after|around|afterThrowing|afterFinally]