如何使用常见的 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))
这些是我的一些功能,我需要写一个通用的功能,看看功能是否运行没有错误。我尝试使用 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 调用失败时被调用。
以下示例确实实现了 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))