문제

내 응용 프로그램 중 하나에 대한 글로벌 오류 처리 "모듈"을 작성하고 있습니다.

내가 원하는 기능 중 하나는 기능을 try{} catch{} 해당 함수의 모든 호출이 내 글로벌 로깅 방법을 호출하는 오류 처리 코드가 자동으로 표시되도록 블록. (시도/캐치 블록으로 모든 곳에서 코드 오염을 피하기 위해).

그러나 이것은 JavaScript의 저수준 기능에 대한 나의 이해를 약간 넘어서는 것입니다. .call 그리고 .apply 방법, 그리고 this 예어.

프로토 타입을 기반 으로이 코드를 썼습니다 Function.wrap 방법:

Object.extend(Function.prototype, {
  TryCatchWrap: function() {
    var __method = this;
    return function() {
            try { __method.apply(this, arguments) } catch(ex) { ErrorHandler.Exception(ex); }
    }
  }
});

다음과 같이 사용됩니다.

function DoSomething(a, b, c, d) {
    document.write(a + b + c)
    alert(1/e);
}

var fn2 = DoSomething.TryCatchWrap();
fn2(1, 2, 3, 4);

그 코드는 완벽하게 작동합니다. 6 인쇄를 한 다음 글로벌 오류 핸들러를 호출합니다.

내 질문은 : 래핑 함수가 객체 내에있을 때 무언가가 깨지고 "이"연산자를 사용합니까? 나는 .Apply를 부르고 거기에 무언가를 전달하기 때문에 약간 걱정하고있다.

도움이 되었습니까?

해결책

개인적으로 내장 된 물건을 오염시키는 대신 데코레이터 기술과 함께 갈 것입니다.

var makeSafe = function(fn){
  return function(){
    try{
      return fn.apply(this, arguments);
    }catch(ex){
      ErrorHandler.Exception(ex);
    }
  };
};

당신은 그것을 사용할 수 있습니다 :

function fnOriginal(a){
  console.log(1/a);
};

var fn2 = makeSafe(fnOriginal);
fn2(1);
fn2(0);
fn2("abracadabra!");

var obj = {
  method1: function(x){ /* do something */ },
  method2: function(x){ /* do something */ }
};

obj.safeMethod1 = makeSafe(obj.method1);
obj.method1(42);     // the original method
obj.safeMethod1(42); // the "safe" method

// let's override a method completely
obj.method2 = makeSafe(obj.method2);

그러나 프로토 타입을 수정하고 싶다면 다음과 같이 쓸 수 있습니다.

Function.prototype.TryCatchWrap = function(){
  var fn = this; // because we call it on the function itself
  // let's copy the rest from makeSafe()
  return function(){
    try{
      return fn.apply(this, arguments);
    }catch(ex){
      ErrorHandler.Exception(ex);
    }
  };
};

명백한 개선은 MATEAFE ()를 매개 변수화하여 캐치 블록에서 호출 할 기능을 지정할 수 있습니다.

다른 팁

2017 답변: ES6 만 사용하십시오. 다음 데모 기능이 주어지면 :

var doThing = function(){
  console.log(...arguments)
}

외부 라이브러리가 필요하지 않고 자신의 래퍼 기능을 만들 수 있습니다.

var wrap = function(someFunction){
  var wrappedFunction = function(){
    var args = [...arguments].splice(0)
    console.log(`You're about to run a function with these arguments: \n     ${args}`)
    return someFunction(args)
  }
  return wrappedFunction
}

사용:

doThing = wrap(doThing)

doThing('one', {two:'two'}, 3)

2016 답변: 사용 wrap 기준 치수:

아래의 예에서는 랩핑합니다 process.exit(), 그러나 이것은 다른 기능 (브라우저 JS 포함)과 함께 행복하게 작동합니다.

var wrap = require('lodash.wrap');

var log = console.log.bind(console)

var RESTART_FLUSH_DELAY = 3 * 1000

process.exit = wrap(process.exit, function(originalFunction) {
    log('Waiting', RESTART_FLUSH_DELAY, 'for buffers to flush before restarting')
    setTimeout(originalFunction, RESTART_FLUSH_DELAY)
});

process.exit(1);

object.extend (function.prototype, {Object.extend Google Chrome Console에서 '정의되지 않은'잘 알려줍니다. 여기에 몇 가지 작업이 있습니다.

    Boolean.prototype.XOR =
//  ^- Note that it's a captial 'B' and so
//      you'll work on the Class and not the >b<oolean object
        function( bool2 ) { 

           var bool1 = this.valueOf();
           //         'this' refers to the actual object - and not to 'XOR'

           return (bool1 == true   &&   bool2 == false)
               || (bool1 == false   &&   bool2 == true);
        } 

alert ( "true.XOR( false ) => " true.XOR( false ) );

따라서 object.extend (function.prototype, {...}) 대신 : function.prototype.extend = {}를 좋아합니다.

좋은 구식으로 기능 포장 :

//Our function
function myFunction() {
  //For example we do this:
  document.getElementById('demo').innerHTML = Date();
  return;
}

//Our wrapper - middleware
function wrapper(fn) {
  try {
    return function(){
      console.info('We add something else', Date());
      return fn();
    }
  }
  catch (error) {
    console.info('The error: ', error);
  }
}

//We use wrapper - middleware
myFunction = wrapper(myFunction);

ES6 스타일에서도 마찬가지입니다.

//Our function
let myFunction = () => {
  //For example we do this:
  document.getElementById('demo').innerHTML = Date();
  return;
}

//Our wrapper - middleware
const wrapper = func => {
  try {
    return () => {
      console.info('We add something else', Date());
      return func();
    }
  }
  catch (error) {
    console.info('The error: ', error);
  }
}

//We use wrapper - middleware
myFunction = wrapper(myFunction);

네임 스페이스를 오염시키는 한, 나는 실제로 그들을 더 오염시킬 것입니다 ... JS에서 발생하는 모든 일이 어떤 종류의 이벤트에 의해 시작되기 때문에 프로토 타입 이벤트 내에서 마법의 래퍼 기능을 호출 할 계획입니다. .observe () 메소드이므로 어디에서나 호출 할 필요가 없습니다.

물론이 모든 것의 다운 사이드를 볼 수 있지만,이 특정 프로젝트는 어쨌든 프로토 타입과 크게 연결되어 있으며,이 오류 처리기 코드를 가능한 한 글로벌이므로 큰 문제는 아닙니다.

답변 해주셔서 감사합니다!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top