如何使用常见的 try-catch 来处理 Javascript 中的每个给定函数?

How to use common try-catch for processing every given function in Javascript?

这些是我的一些功能,我需要写一个通用的功能,看看功能是否运行没有错误。我尝试使用 try/catch 方法。但我只能在每个功能上单独执行此操作。

function fisrt(){
 console.log("First");
};

function second(){
 console.log("Second");
}

function third(){
 console.log("Third");
}
fisrt();
second();
third();

我在 try-catch 中编写了每个函数。有没有一种方法可以为所有函数编写一个通用的 try-catch。

try {
     (function first() {
       console.log("ffgdf")
    })();

 }catch (e) {
      console.log( "won't work" );
    }

您可以定义一个包装函数,将您想要的函数作为参数,并将其包装在 try catch 中。

function wrapper(fn) {
    try {
        fn();
    } catch(error) {
        console.error(error);
    }
}

然后给出你原来的函数:

function first() {
    console.log("First");
};

function second() {
    console.log("Second");
}

function third() {
    console.log("Third");
}

您可以使用包装函数测试每一个:

wrapper(first);
wrapper(second);
wrapper(third);

无需为每个函数添加 try catch。

关于两年前录用答案的介绍句...

You could define a wrapper function, that takes your desired function as a parameter, and wraps it in a try catch.

...这部分可以包含(一个)抽象,其中还可以提供调用失败的(不同)处理(catch 和异常条款)。

例如,如果有人提供包装 function/method 的功能,其方式不仅提供 try catch,而且还采用 异常处理 考虑到,可以轻松完成任务,就像 OP 要求的那样,主要是关于 自动创建和处理列表的可编程方法functions/methods 将在抑制 unintended/unexpected 调用失败时被调用。

以下示例确实实现了 and afterFinally, two method modifier 方法,每个方法都使用异常处理程序作为其第一个参数来处理原始 function/method。

利用提供的抽象方法本身归结为编写reduce处理函数数组的功能 通过使用自己的一组参数调用每个函数并收集其调用成功状态 ...

function first(...args) {
  console.log("first :: does succeed :: argsList :", args);
  return args.join(', ');
}
function second(...args) {
  console.log("second :: going to fail :: argsList :", args);
  throw new Error('2nd invocation failed.');
}
function third(...args) {
  console.log("third :: going to fail :: argsList :", args);
  throw new Error('3rd invocation failed.');
}
function fourth(...args) {
  console.log("fourth :: does succeed :: argsList :", args);
  return args.join(', ');
}
function fifth(...args) {
  console.log("fifth :: does succeed :: argsList :", args);
  return args.join(', ');
}


/**
 *  reduce functionality which processes an array of functions.
 */
function collectResultAfterThrowing(collector, fct, idx) {
  function afterThrowingHandler(error, argsArray) {
    // - can access the try-catch exception and the arguments
    //   that have been passed prior to the invocation failure.
    return {
      success: false,
      failure: {
        message: error.toString(),
        argsList: Array.from(argsArray)
      }
    }
  }
  function unifyResult(value) {
    return ((
         value
      && value.hasOwnProperty('success')
      && (value.success === false)
      && value
    ) || { success: true, value });
  }
  collector.results.push(
    unifyResult(fct                         // - modify original function towards an
      .afterThrowing(afterThrowingHandler)  //   `afterThrowing` handling of its try-catch result(s).
      .apply(null, collector.listOfArguments[idx])
    )
    // - an `afterThrowing` modified function does always return either the result of the
    //   original function's invocation or the return value of its 'afterThrowing' handler.
  );
  return collector;
}


/**
 *  reduce functionality which processes an array of functions.
 */
function collectResultAfterFinally(collector, fct, idx) {
  function isError(type) {
    return (/^\[object\s+Error\]$/).test(Object.prototype.toString.call(type));
  }
  function createResult(value) {
    return (isError(value) && {
      success: false,
      message: value.toString()
    } || {
      success: true,
      value
    });
  }
  collector.results.push(
    createResult(fct            // - modify original function towards an
      .afterFinally(() => null) //   `afterFinally` handling of its try-catch result(s).
      .apply(null, collector.listOfArguments[idx])
    )
    // - an `afterFinally` modified function does always return either the result of the
    //   original function's invocation or the try-catch exception of the invocation attempt.
  );
  return collector;
}


// ... two times, each the actual task, 
// ... once based on "afterThrowing" and
// ... once based on "afterFinally" ...

console.log('"afterThrowing" based try-and-catch results :', [

    first,
    second,
    third,
    fourth,
    fifth

  ].reduce(collectResultAfterThrowing, {

    listOfArguments: [
      ['foo', 'bar'],
      ['baz', 'biz'],
      ['buz', 'foo'],
      ['bar', 'baz'],
      ['biz', 'buz']
    ],
    results: []

  }).results
);
console.log('\n\n\n');

console.log('"afterFinally" based try-and-catch results :', [

    first,
    second,
    third,
    fourth,
    fifth

  ].reduce(collectResultAfterFinally, {

    listOfArguments: [
      ['foo', 'bar'],
      ['baz', 'biz'],
      ['buz', 'foo'],
      ['bar', 'baz'],
      ['biz', 'buz']
    ],
    results: []

  }).results
);
.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] }';

    function afterFinally/*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, error;
          try {
            result = proceed.apply(context, args);

          } catch (exception) {

            error = exception;

          } // finally { ... }

          result = (error || result);
          handler.call(context, result, args);

          return result;
        }

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

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

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

  }(Function));
</script>

如果您希望获得 "throwed" 异常,您可以使用 Promise.all.

function parent() {
    function first() {
        console.log('First');
        throw new Error('First error');
    }
    
    function second() {
        console.log('Second');
    }
    
    function third() {
        console.log('Third');
    }
    
    return Promise.all([
        first(),
        second(),
        third(),
    ])
}

parent()
     .then(result => console.log(result))
     .catch(error => console.error(error))