2016-07-21 5 views
3

フェッチの約束が解決されていない場合、一定の時間が経過すると、ユーザーにタイムアウトエラーが表示されます。reduxを使用するfetch promiseに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が発生することはありません。詳細はこちら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

うわー、すばらしい、このアイデアが大好きで、本当にうまくいった!どうもありがとうございます! '' ...要求は=( 'blah.com/data')をフェッチさせ、その後、 '[Promise.raceを返す:あなたは新しい約束を作成する必要はありませんので、約束を返しfetch' –

+5

'タイムアウト、要求] ... ' – 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の答えをマークしなければならなかった –

関連する問題