2013-02-01 1 views
2

jQuery Deferred의 독립 실행 형 구현 (git repo)을 사용하고 있습니다. 질문을 단순하게 유지하면서 어떤 함수에서든지 var status = _.Deferred()을 만들고 status.promise()을 반환하면 해당 함수 내의 모든 단계에 try catch를 추가해야합니까? reject 오류시 지연?항상 try catch 내의 지연 해결

답변

1

자바 스크립트에서 try/catch는 Java와 마찬가지로 삶의 방식이 아닙니다. 그 이유는 javascript가 예측 가능한 유형의 오류를 피하기 위해 상당히 풍부하다는 것입니다.

Deferred를 거부하는 것은 꼭 필요한 것은 아닙니다. 일반적으로 일부 fail 코드를 실행해야하거나 지연된 이벤트를 해결하는 이후 이벤트를 적극적으로 방지해야하는 경우 이렇게합니다.

해결되지 않은/거부되지 않은 Deferreds가 영원히 정지한다고 생각하는 것이 유혹적입니다. 이것은 반드시 그런 것은 아닙니다. Deferred는 가비지 수집을 위해 직접적으로 또는 약속을 통해 범위에 대한 참조가 존재하지 않을 때 가비지 콜렉션에 사용할 수있게됩니다.

해결 된/거부 된 지연이 자동으로 가비지 수집되는 것으로 생각하는 것이 좋습니다. 이것은 또한 사실이 아닙니다. Deferred에 대한 참조가 여전히 존재한다면, 어떤 범위에서 여전히 메모리에 존재할 것이며, watcher 메소드 (예 : done/fail/always/then)가 나중에 호출 될 수 있다면 유용 할 수 있습니다).

요약하면 GC와 관련하여 Deferreds는 다른 js 개체와 비슷하지만 일반적으로 사용되는 코드 구조로 인해 GC에 사용할 수있게되었을 때이를 찾아 내기가 어렵습니다.

3
약속이 반환되기 전에 약속이 발생할 반환하는 함수 내에서 던지는

때문에, 아니 : 당신이 문제로 실행

function foo() { 
    var status = _.Deferred(); 

    throw 'DOH!'; 

    return status.promise(); // this will never execute 
} 

는 약속을 돌려주는 함수에서 시작 비동기 호출을 던질 수있는 경우 :

이 경우
function bar() { 
    throw 'DOH!'; 
} 

function foo() { 
    var status = _.Deferred(); 

    setTimeout(function() { 
    status.resolve(bar()); 
    }, 0); 

    return status.promise(); 
} 

foo(). 
    fail(function() { 
    // *not* invoked when bar throws 
    }); 

, 당신은 bar에 전화를 포장해야합니다 :

function bar() { 
    throw 'DOH!'; 
} 

function foo() { 
    var status = _.Deferred(); 

    setTimeout(function() { 
    try { 
     status.resolve(bar()); 
    } catch (e) { 
     status.reject(e); 
    } 
    }, 0); 

    return status.promise(); 
} 

foo(). 
    fail(function() { 
    // invoked when bar throws 
    }); 

그러나 콜백을 허용하는 비동기 함수는 자체 오류를 포착하여 결과 또는 오류를 콜백에 전달해야합니다.

비동기 기능을 대신 약속을 반환하는 경우, 당신이 잡을 필요가없는 사실 만들 필요가 없습니다 당신의 자신의 Deferred :

function bar() { 
    var d = _.Deferred(); 

    setTimeout(function() { 
    d.resolve(42); 
    }, 0); 

    return d.promise(); 
} 

function foo() { 
    return bar(). 
    then(function (result) { 
     return result * 2; 
    }). 
    then(function (result) { 
     if (result === 84) { // true 
     throw 'DOH!'; 
     } 
    )); 
} 

foo(). 
    then(function (result) { 
    // *not* invoked 
    }). 
    fail(function (e) { 
    console.log(e.message); // 'DOH!' 
    });