2016-09-27 4 views
1

what-wg를 사용하는 응용 프로그램에서 작업하고 있습니다.약속 체인에 대한 대체 캐치를 정의 하시겠습니까?

fetch('/api/specific/route', fetchDefaults) 
    .then(fetchMiddleware) 
    .then(function(data) { 
    // ... Dispatch case-specific fetch outcome 
    dispatch(specificRouteResponseReceived(data)); 
    }); 

우리는 모든 fetch에 일반, 대체 캐치를 추가 할 :

export function fetchMiddleware(response) { 
    return new Promise(resolve => { 
    resolve(checkStatus(response)); 
    }).then(parseJSON); 
} 

export const fetchDefaults = { 
    credentials: 'same-origin', 
    headers: { 
    'Accept': 'application/json', 
    'Content-Type': 'application/json' 
    } 
}; 

우리는 우리의 기본 미들웨어를 사용/옵션이 방법을 가져 오기 : 우리는 기본 미들웨어 및 옵션이 방법을 가져 정의한 이 같은 다른 단어 뭔가, 응용 프로그램 전반에 걸쳐을 용도 : 코드 중복의

export function fetchGenericCatch(function(error) { 
    showGenericErrorFlashMessage(); 
}) 

fetch('/en/api/user/me/preferences', fetchDefaults) 
    .then(fetchMiddleware) 
    .then(function(data) { 
    dispatch(userPreferencesReceived(data)); 
    }) 
    .catch(fetchGenericCatch); 

많이. 이 모든 작업을 수행 할 수있는 유틸리티 함수/클래스가 필요합니다 (예 : 같이 일하는 것이 뭔가 :

genericFetch('/api/specific/route') // bakes in fetchDefaults and fetchMiddleware and fetchGenericCatch 
    .then(function(data) { 
    dispatch(userPreferencesReceived(data)); 
    }); // gets generic failure handler for free 

genericFetch('/api/specific/route') // bakes in fetchDefaults and fetchMiddleware and fetchGenericCatch 
    .then(function(data) { 
    dispatch(userPreferencesReceived(data)); 
    }) 
    .catch(function(error) { 
    // ... 
    }); // short-circuits generic error handler with case-specific error handler 

주요주의해야 할 점은 일반 catch이 경우 특정 then S/catch ES 후 를 체인해야한다는 것입니다.

whatwg-fetch/ES6 Promises를 사용하여 어떻게 달성 할 수 있을지에 대한 정보가 필요하십니까?

관련 :

이 유사한 게시물이 있지만, 그들은 모두 기본값이 아닌 then의 후 catch ES 실행되는 기본 잡기의 필요성 해결하지 않는 것 :

편집 : 14 시월

가능한 중복 : Promises and generic .catch() statements

+0

함수가 반환 된 후에 사용자가'.then/.catch'es를 추가하더라도 자동으로'.catch' 리스너를 추가하겠다는 점을 이해하고 있습니까? AFAIK는 불가능합니다. – nils

+0

아니요, 캐치되지 않은 오류를 처리 할 기본 약속 인'catch'를 추가하고 싶습니다. 오류가 적용될 수 있다면 --- 캐치 처리기가 정의되지 않았다면 말입니다. –

답변

0

, 여기에 한 최악의 옵션이 아닙니다 오류 처리기는 DRY이므로

fetch(...) 
... 
.catch(importedFetchHandler); 

그것은 아무런 문제가 발생하지 않습니다 및 처리되지 않은 거부 이벤트가 어떤 약속이 포착되지 않은 남지 않도록하기 위해 존재 블루 버드와 V8 약속의 동작을 준수합니다.그런

function catchyFetch(...args) { 
    return new CatchyPromiseLike(fetch(...args)); 
} 

는 A 사용할 수 있습니다

function CatchyPromiseLike(originalPromise) { 
    this._promise = originalPromise; 

    this._catchyPromise = Promise.resolve() 
    .then(() => this._promise) 
    .catch((err) => { 
    console.error('caught', err); 
    }); 

    // every method but 'constructor' from Promise.prototype 
    const methods = ['then', 'catch']; 

    for (const method of methods) { 
    this[method] = function (...args) { 
     this._promise = this._promise[method](...args); 

     return this; 
    } 
    } 
} 

약속 같은 :


이 도달하는 가장 간단한 방법은 fetch 약속에 대한 약속과 같은 래퍼를 소개하는 것입니다 자연적인 한계가있다. 실제 약속을 변환 할 경우

부작용이 삭제됩니다

var promise = catchyFetch(...); 

setTimeout(() => { 
    promise.then(() => /* won't be caught */); 
}); 

:

Promise.resolve(catchyFetch(...)).then(() => /* won't be caught */); 

그리고 비동기 체인과 잘 재생되지 않습니다 (이것은 더 노의 모든 약속에 대한 없음)

좋은 대안은 Bluebird입니다. 바퀴를 발명 할 필요가 없습니다. 기능은 사랑받는 것입니다. Local rejection events은 정확히 필요한 것처럼 보입니다.

// An important part here, 
// only the promises used by catchyFetch should be affected 
const CatchyPromise = Bluebird.getNewLibraryCopy(); 

CatchyPromise.onPossiblyUnhandledRejection((err) => { 
    console.error('caught', err); 
}); 

function catchyFetch(...args) { 
    return CatchyPromise.resolve(fetch(...args)); 
} 

쉽습니다.

+0

Bluebird 'onPossiblyUnhandledRejection' 솔루션을 좋아합니다. JS Bin의 매력처럼 작동합니다. 아직 완전히 신비로운 이유 중 일부는 바벨 설정에서 작동하지 않습니다. 우리는 그것을 별도로 알아낼 것입니다 :) 다시 한번 감사드립니다. http://jsbin.com/rerafucoza/edit?js,console –

+0

당신을 진심으로 환영합니다. 최신 Bluebird 릴리스 만 getNewLibraryCopy를 지원합니다. – estus

+0

그래도 우리는 3.4.6도 사용하고 있습니다. 함수 호출이 존재한다. 여전히 효과가 없습니다. 매우 이상합니다! 코드는 모두 JS Bin과 일치하지만 오류는 발견되지 않습니다. 여러 가지 babel 사전 설정과 플러그인을 시도하여 bluebird를 다른 방법으로 주입하는 방법을 확인합니다. 월요일의 일이 더 명확 해 보일 수도 있습니다. –

0

나는 해결책은 간단하다 생각과 같은 : 특별한 오류를 필요로하지 않는다

export function genericFetch(url, promise, optionOverrides) { 
    const fetchOptions = {...fetchDefaults, ...optionOverrides}; 
    return fetch(url, fetchOptions) 
    .then(fetchMiddleware) 
    .then(promise) 
    .catch(function(error) { 
     showGenericFlashMessage(); 
    }); 
} 

유스 케이스 핸들러는 다음과 같이 간단하게 사용할 수 있습니다.

genericFetch('/api/url', function(data) { 
    dispatch(apiResponseReceived(data)); 
}); 

특별한 캐치, 또는 더 복잡한 사슬을 필요로 유스 케이스, 본격적인 약속을 전달할 수 있습니다 WET 코드를 갖는

genericFetch('/api/url', function(response) { 
    return new Promise(resolve, reject => { 
    dispatch(apiResponseReceived(data)); 
    }).catch(nonGenericCaseSpecificCatch); // short-circuits default catch 
}); 
관련 문제