2017-10-05 9 views
1

約束のあるR.condをどうすれば使えますか?Ramdaで約束の条件付き

このような何か...

const fetchBin = (url) => fetch(`https://httpbin.org${url}`).then((response) => { 
 
    var contentType = response.headers.get("content-type"); 
 
    if(contentType && contentType.includes("application/json")) { 
 
     return response.json(); 
 
    } 
 
    throw new TypeError("Oops, we haven't got JSON!"); 
 
}) 
 

 
const testStatus = (status) => fetchBin(`/status/${status}`); 
 

 
const isOk = R.propEq('statusCode', 200); 
 
const testCond = R.cond([ 
 
    [ R.pipeP(testStatus, isOk), (resp) => console.log('The resp is ', resp) ], 
 
    [ R.T, (code) => console.log('The resp is NOT ok', code) ] 
 
]) 
 

 
testCond(404) 
 
// R.pipeP(testStatus, isOk)(404)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.24.1/ramda.min.js"></script>

+0

Ramadaのドキュメントによれば、述語は 'cond'の純粋な関数であるはずなので、' testStatus'の 'then'の中に' testCond'部分があるべきだと思います。 –

答えて

2

私は、これはあなたが後にあるかと思い、testStatusとそれを構成することにより、あなたはresponseオブジェクトを取得することが可能と条件分岐を行う必要があります。

const fetchBin = (url) => fetch(`https://httpbin.org${url}`).then((response) => { 
 
    var contentType = response.headers.get("content-type"); 
 
    if(contentType && contentType.includes("application/json")) { 
 
     return response.json(); 
 
    } 
 
    throw new TypeError("Oops, we haven't got JSON!"); 
 
}) 
 

 
const testStatus = (status) => fetchBin(`/status/${status}`); 
 

 
const isOk = R.propEq('statusCode', 200); 
 
const testCond = R.pipeP(testStatus, R.cond([ 
 
    [isOk, resp => console.log('The resp is OK :' + resp.statusCode)], 
 
    [R.T, resp => console.log('The resp is NOT OK :' + resp.statusCode)] 
 
])); 
 

 
testCond(404) 
 
// R.pipeP(testStatus, isOk)(404)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.24.1/ramda.min.js"></script>

+0

こんにちは@MinusFour、私はあなたの提案を試みたが、うまくいきませんでした。 'R.pipeP(testStatus、/ *約束が解決されない場合(この場合catch)* /)' [ここ](https://runkit.com/ridermansb)で確認できます。/ramda-promises) – ridermansb

+1

これはcatch節に依存すると多少問題になりますが、拒否しても約束を果たさなければなりません。 400のステータスコードでも、400のステータスコードプロパティを持つJSON回答を返していたという印象を受けました。 – MinusFour

2

新鮮な視点の周り

それは我々が我々のプログラミング言語を曲げたものであることを自分自身を思い出させるために良いことだ、ではない他の方法

私は、あなたが間違った経路。 fetchBinは、私たちが本当に探している男のストローマンです。 URLをとり、解析されたJSONレスポンスを返す関数が必要です。 fetchJSON

があるから、私たちはfetchJSONを使用してfetchBinを実装する、のは、この男を呼び出してみましょう - リソースが404状態または間違ったコンテンツタイプで200ステータスを返すかどうかは関係ありません(下記のXMLの例を参照) - のいずれかの方法をその約束はエラーハンドラ(console.errorの下、あるいは.then(console.log).catch(console.error))に正しくルーティングされます。ここでのポイントは、明確ではない場合は、fetchBinはHTTPステータスコードの内容レスポンスのContent-Typeヘッダーは、解析されたJSONを要求し、残りの部分について心配することを止めさせます。

これを共有する理由は、あなたが特定の考え方にこだわらないようにすることです。 R.condはかなりの形で、の形式です。正直なところ正式な言い方をすると、プログラムのフォークの意味を配列でケージングし、プログラムでは決して使用できない条件分岐を保持するようにサンクを作成します。 true怠惰は、厳密に評価されたJavaScriptでのみ利用可能です。if/elseまたは?:です。一体、私たちもR.pipe、またはR.pipeP、またはRですべてを必要としてしまうなかった - それらなしであなたはまだ私たちがR.condのような硬質のフォームから自分のバインドを解除すると

、物事はかなり自然に一緒に収まるよう、不要な仕事をやっています。 ..

const fetchJSON = url => 
 
    fetch (url) 
 
    .then (responseOK) 
 
    .then (parseJSON) 
 

 
const responseOK = (response) => 
 
    { 
 
    if (response.status >= 200 && response.status < 300) 
 
     return response 
 
    else 
 
     throw Object.assign (Error (response.statusText), { response }) 
 
    } 
 

 
const parseJSON = response => 
 
    response.json() 
 
    
 
const fetchBin = (url) => 
 
    fetchJSON ('https://httpbin.org' + url) 
 

 
fetchBin ('/anything?a=b') .then (console.log, console.error) 
 
// all things good ! 
 
// => { args: {a: 'b'}, data: '' ... } 
 

 
fetchBin ('/status/404') .then (console.log, console.error) 
 
// non-200 status goes to error handler 
 
// => { Error: NOT FOUND ..., response } 
 

 
fetchBin ('/xml') .then (console.log, console.error) 
 
// bad JSON goes to error handler 
 
// => SyntaxError: Unexpected token < in JSON at position 0


[OK]をので、私たちはそこRが、この答えを必要としませんでしたそれを一般的な経験則として暗示することを意味するものではありません。Ramdaは優れたツールであり、関数型プログラミングについて多くのことを教えてくれることがあります。ちょっと前に戻ってプログラムを表現できるかどうかを評価してください。あなたは言語(ライブラリ、またはfunction; R.cond)が必要です

関連する問題