2016-07-21 1 views
3

가져 오기 약속이 해결되지 않은 경우 일정 시간이 지나면 사용자에게 시간 초과 오류를 표시하려고합니다.redux를 사용하는 약속 가져 오기에 setTimeout을 추가하는 방법은 무엇입니까?

은 여기 가져 오기 위해에서는 setTimeout를 추가하는 좋은 예는 본 적이 : https://github.com/github/fetch/issues/175

을하지만 어떻게 내가 또한 REDUX을 사용하여 약속을 가져 타임 아웃 처리 할 수 ​​있습니다? 예 :

export function getData() { 
    return (dispatch, getState) => { 
    fetch('blah.com/data') 
    .then(response => response.json()) 
    .then(json => dispatch(getDataSuccess(json))) 
    .catch(
     error => { 
     console.log(error) 
     } 
    ) 
     dispatch({ 
     type: DATA_FETCH_REQUEST 
     }) 
    } 
} 

감사합니다!

당신이 언급 한 GitHub의에서 조각을 바탕으로

답변

21

나는 Promise.race를 사용하는 이유가 있기를 원했지만,이 사용 사례에서는 완벽하게 작동합니다. Promise.race는 첫 번째 해결 또는 첫 번째 거부를 기다립니다. 따라서 불만이 먼저 발생하면 Promise.race에서 then을 발사하지 않습니다. More here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race. 죄송합니다. 코드를 테스트 할 기회가 없었습니다.

export function getData() { 
    return (dispatch, getState) => { 
    let timeout = new Promise((resolve, reject) => { 
     setTimeout(reject, 300, 'request timed out'); 
    }) 
    let fetch = new Promise((resolve, reject) => { 
     fetch('blah.com/data') 
     .then(response => response.json()) 
     .then(json => resolve(json)) 
     .catch(reject) 
    }) 
    return Promise 
     .race([timeout, fetch]) 
     .then(json => dispatch(getDataSuccess(json))) 
     .catch(err => dispatch(getDataTimeoutOrError(err))) 
    } 
} 
+0

와우, 멋지 네요! 'Promise.race'에 대해 몰랐다 – amann

+0

와우, 굉장해,이 아이디어가 정말 좋았어! 정말 고맙습니다! 새 약속 만들 필요가 없습니다 있도록 약속을 반환 fetch' –

+5

'('blah.com/data') 가져 = 가'요청하자를 ...' 다음 'Promise.race를 [반환 시간 초과, 요청] ...' – johans

5

, 당신은 아마 이런 식으로 뭔가를 할 수 있습니다 : 당신이 요청이 실패 사용자에게 정보를 표시 할 경우, 처리 할 수 ​​있습니다

function timeoutPromise(ms, promise) { 
    return new Promise((resolve, reject) => { 
    const timeoutId = setTimeout(() => { 
     reject(new Error('Timeout')); 
    }, ms); 
    promise.then(
     (res) => { 
     clearTimeout(timeoutId); 
     resolve(res); 
     }, 
     (err) => { 
     clearTimeout(timeoutId); 
     reject(err); 
     } 
    ); 
    }) 
} 

export function getData() { 
    return (dispatch, getState) => { 
    dispatch({type: DATA_FETCH_REQUEST}); 

    timoutPromise(5000, fetch('blah.com/data')) 
    .then(response => response.json()) 
    .then(json => dispatch(getDataSuccess(json))) 
    .catch(
     error => { 
     // Change this as necessary 
     dispatch({type: DATA_FETCH_FAILED}); 
     console.log(error); 
     } 
    ); 
    } 
} 

유형은 DATA_FETCH_FAILED입니다.

+0

고마워요! 방금 DATA_FETCH_REQUEST 작업이 계속 진행되고 약속 된 연결 고리의 일부가 아니기 때문에 '처리되지 않은 잠재적 약속 거부'가 발생했습니다. –

+0

계속 하시겠습니까? 'getData' 함수를 호출 할 때마다 호출되어야합니다. 또한'DATA_FETCH_REQUEST'는 Promise 체인 외부에서 실행되는 것이 좋습니다. 항상'fetch'와는 별도로 실행되므로 (가져 오기 호출 전에 이동시킬 수도 있습니다). 약속의 거부가 어디에서오고 있는지 그리고 왜 그 이유를 찾을 수 있습니까? – amann

+0

내 잘못 됐어. 내가 어디에서 액션을 호출했는지 componentDidUpdate가 있었는데, 그게 루프를 일으켰다. 이 일이 정말 고마워요. 죄송합니다. 제가 생각했듯이 .race 답변을 표시해야했습니다. 아이디어가 존재하고 그 아이디어를 좋아한다는 것을 모를 때 –

관련 문제