2016-09-27 2 views
1

私はwhat-wgを全面的に取得するアプリケーションを開発中です。私たちは、デフォルトでは、ミドルウェアやオプションをこのようにフェッチ定義しました:プロミスチェーンのフォールバックキャッチを定義しますか?

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' 
    } 
}; 

私たちは、このよう私たちのデフォルトのミドルウェア/フェッチオプションを使用します。

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

我々はすべてのfetchにジェネリック、フォールバックキャッチを追加しますこのようなつまり何かに、アプリケーション全体な用途:コードの重複の

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 sおよびcatch ES後を実行し、デフォルトのキャッチの必要性に対処していないようです:

編集10月14日:

可能な重複:

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

特殊なエラーを必要としないユースケース:Promises and generic .catch() statements

+0

関数が返った後にユーザーが '.then/.catch'esを追加したとしても、自動的に' .catch'リスナーを追加したいということを正しく理解していますか? AFAIKはできません。 – nils

+0

いいえ、キャッチされていないエラーを処理するデフォルトの約束 'catch'を追加します。エラーが適用可能であれば、' catch'ハンドラが別途定義されていない場合です。 –

答えて

0

は、ここにいる限り最悪のオプションではありませんエラーハンドラはDRYであるためです。

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

それは問題ないし、未処理拒否イベントが何も約束がキャッチされないままにされていないことを確認するために存在するブルーバードとV8の約束、の動作に準拠しています。そのような

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

のように使用することができ

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 */); 

そしてそれは、非同期チェーンとうまく再生されません(これは無なしすべての約束のためではありません)

良い選択肢はブルーバードです。そこにホイールを作り出す必要はなく、機能は愛されているものです。 Local rejection eventsは、必要なものとまったく同じように見えます。

Phew、簡単でした。

+0

BluebirdのonPossiblyUnhandledRejectionソリューションが大好きです。 JS Binの魅力のように動作します。まだまったく神秘的な理由のために、私たちのバベルの設定では機能していません。私達は別にそれを理解するでしょう:)もう一度感謝http://jsbin.com/rerafucoza/edit?js,console –

+0

よろしくお願いします。最新のBluebirdリリースのみがgetNewLibraryCopyをサポートしています。 – estus

+0

さて、3.4.6も使用しています。関数呼び出しは存在しています。まだ、効果は、非常に奇妙な!コードはすべてJS Binと一致しますが、エラーは検出されません。さまざまなバベルプリセットとプラグインを試して、ブルーバードを適切に注入する方法を見てみましょう。月曜日のものはもっと明白に見えるかもしれません。 –

0

私は解決策をと同じくらい簡単だと思いますハンドラはこのように単純に使用できます。

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 
}); 
関連する問題